diff --git a/icu4j/build.xml b/icu4j/build.xml
index 9182ef4..46b3d01 100644
--- a/icu4j/build.xml
+++ b/icu4j/build.xml
@@ -183,13 +183,6 @@
         <delete dir="${out.dir}"/>
         <delete dir="${module.dir}"/>
         <delete dir="${cldr.release.dir}"/>
-
-        <available file="eclipse-build" type="dir" property="eclipse-build.dir.present"/>
-        <antcall target="_clean.eclipse-build"/>
-    </target>
-
-    <target name="_clean.eclipse-build" if="eclipse-build.dir.present">
-        <ant dir="eclipse-build" target="clean" inheritAll="false"/>
     </target>
 
     <target name="ivy-clean">
diff --git a/icu4j/eclipse-build/build-local.properties.template b/icu4j/eclipse-build/build-local.properties.template
deleted file mode 100644
index 7427fa8..0000000
--- a/icu4j/eclipse-build/build-local.properties.template
+++ /dev/null
@@ -1,39 +0,0 @@
-# © 2016 and later: Unicode, Inc. and others.
-# License & terms of use: http://www.unicode.org/copyright.html
-################################################################################
-# Copyright (C) 2014-2015, International Business Machines Corporation and
-# others. All Rights Reserved.
-################################################################################
-
-# Eclipse installation location
-# Specify the folder that contains eclipse.exe, for example: eclipse.home=C:/eclipse
-#
-# Note:
-#      By default, this value is set by an environment variable 'ECLIPSE_HOME'.
-#      You could uncomment below and specify the path in this file alternatively (recommended). 
-#
-#eclipse.home=
-
-#
-# Java 7 runtime jar location
-# Specify jar file path(es) including Java runtime classes.
-#
-# Note: 
-#   Java runtime classes are stored in multiple jar files in modern JREs.
-#   To get the full list of jar files included in JRE, you can write a simple
-#   code printing system property "sun.boot.class.path".
-#
-# For example:
-#
-# java.rt=C:/java7/jre/lib/resources.jar;C:/java7/jre/lib/rt.jar;\
-#     C:/java7/jre/lib/sunrsasign.jar;C:/java7/jre/lib/jsse.jar;\
-#     C:/java7/jre/lib/jce.jar;C:/java7/jre/lib/charsets.jar;
-#     C:/java7/jre/lib/jfr.jar;C:/java7/jre/classes
-#
-# NOTE: slashes must be forward slashes. Backslashes will NOT work as path separator.
-#
-# IF java.rt variable has embedded space(s)...
-#   ...each element containing an embedded space java.rt must individually quoted and the elements separated by a semi-colon.
-#   ex. "C:/Program Files/IBM/JDK7/jre/lib/vm.jar";"C:/Program Files/IBM/JDK7/jre/lib/core.jar"
-#                                                ^^^
-#java.rt=
diff --git a/icu4j/eclipse-build/build.xml b/icu4j/eclipse-build/build.xml
deleted file mode 100644
index 9020b8e..0000000
--- a/icu4j/eclipse-build/build.xml
+++ /dev/null
@@ -1,409 +0,0 @@
-<!--
-/*
-* © 2016 and later: Unicode, Inc. and others.
-* License & terms of use: http://www.unicode.org/copyright.html
-*******************************************************************************
-* Copyright (C) 2010,2016, International Business Machines Corporation and    *
-* others. All Rights Reserved.                                                *
-*******************************************************************************
-*/
--->
-
-<project name="icu4j-eclipse" default="build" basedir=".">
-  <property file="build-local.properties"/>
-  <property file="build.properties"/>
-
-  <property name="out.dir" value="out"/>
-  <property name="eclipse.projects.dir" value="${out.dir}/projects"/>
-
-  <property name="main.dir" value="../main"/>
-  <property name="shared.dir" value="${main.dir}/shared"/>
-
-  <import file="${shared.dir}/build/common-targets.xml"/>
-  <property file="${shared.dir}/build/common.properties"/>
-  <property file="${shared.dir}/build/locations.properties"/>
-
-  <property environment="env"/>
-
-  <target name="clean" description="Delete all build outputs">
-    <delete dir="${out.dir}"/>
-  </target>
-
-  <target name="build"
-          depends="checkProps,initEnv,icuProjectFiles,icuTestsProjectFiles,icuBaseProjectFiles,icuBaseTestsProjectFiles"
-          description="Build icu4j plug-ins">
-
-    <!-- copy OSGi jar file to baseLocation -->
-    <mkdir dir="${eclipse.projects.dir}/baseLocation/features"/>
-    <mkdir dir="${eclipse.projects.dir}/baseLocation/plugins"/>
-    <copy toDir="${eclipse.projects.dir}/baseLocation/plugins" file="${eclipse.osgi.jar}"/>
-
-    <!-- copy PDE build script files and run the build -->
-    <pathconvert property="eclipse.projects.dir.full" dirsep="/">
-      <path location="${basedir}/${eclipse.projects.dir}"/>
-    </pathconvert>
-
-    <antcall target="runEclipsePDEBuild">
-      <param name="icu.plugin.id" value="com.ibm.icu"/>
-    </antcall>
-
-    <antcall target="runEclipsePDEBuild">
-      <param name="icu.plugin.id" value="com.ibm.icu.base"/>
-    </antcall>
-
-  </target>
-
-  <target name="initEclipseHome"
-          if="env.ECLIPSE_HOME"
-          unless="eclipse.home"
-          description="Initialize the property eclipse.home from the environment variable ECLIPSE_HOME">
-    <property name="eclipse.home" value="${env.ECLIPSE_HOME}"/>
-  </target>
-
-  <target name="checkProps" depends="initEclipseHome">
-      <fail message="Eclipse home (eclipse.home or env.ECLIPSE_HOME) is not set">
-        <condition>
-          <or>
-            <equals arg1="${eclipse.home}" arg2=""/>
-            <not>
-              <isset property="eclipse.home"/>
-            </not>
-          </or>
-        </condition>
-      </fail>
-      <fail message="Java runtime jar path (java.rt) is not set">
-        <condition>
-          <or>
-            <equals arg1="${java.rt}" arg2=""/>
-            <not>
-              <isset property="java.rt"/>
-            </not>
-          </or>
-        </condition>
-      </fail>
-  </target>
-
-  <target name="initPluginVersion">
-    <tstamp>
-      <format property="build.date" pattern="yyyyMMdd"/>
-    </tstamp>
-    <property name="icu4j.eclipse.build.version.string" value="${icu4j.plugin.impl.version.string}.v${build.date}"/>
-  </target>
-
-  <target name="initEnv"
-          depends="checkProps,initEclipseLauncher,initEclipseOSGiJar,initEclipsePDE"
-          description="Initialize eclipse PDE build environment">
-    <echo message="[PDE build configuration properties]"/>
-    <echo message="    Ant version:     ${ant.version}"/>
-    <echo message="    Eclipse home:    ${eclipse.home}"/>
-    <echo message="    Launcher jar:    ${eclipse.launcher}"/>
-    <echo message="    OSGi bundle jar: ${eclipse.osgi.jar}"/>
-    <echo message="    Base OS:         ${eclipse.baseos}"/>
-    <echo message="    Base WS:         ${eclipse.basews}"/>
-    <echo message="    Base ARCH:       ${eclipse.basearch}"/>
-    <echo message="    java.rt:         ${java.rt}"/>
-      
-    <!-- try and detect use of backslashes  -->
-    <condition property="java-rt-has-noSlashes">
-        <matches pattern="/" string="${java.rt}"/>
-    </condition>      
-    <fail message="java.rt variable has no slashes!" unless="java-rt-has-noSlashes"/>
-
-  </target>
-    
-  <target name="initEclipseLauncher"
-          if="eclipse.home"
-          description="Locate org.eclipse.equinox.launcher jar file for eclipse 3.3 and beyond">
-    <first id="equinox.launcher">
-      <fileset dir="${eclipse.home}/plugins">
-        <include name="org.eclipse.equinox.launcher_*.jar"/>
-      </fileset>
-    </first>
-    <pathconvert property="eclipse.launcher" dirsep="/" refid="equinox.launcher"/>
-  </target>
-
-  <target name="initEclipseOSGiJar"
-          if="eclipse.home"
-          description="Locate org.eclipse.osgi plugin jar file">
-    <first id="osgi.bundle">
-      <fileset dir="${eclipse.home}/plugins">
-        <include name="org.eclipse.osgi_*.jar"/>
-      </fileset>
-    </first>
-    <pathconvert property="eclipse.osgi.jar" dirsep="/" refid="osgi.bundle"/>
-  </target>
-
-  <target name="initEclipsePDE"
-          depends="locateEclipsePDE"
-          if="eclipse.pde.dir"
-          description="Set up PDE runtime arguments">
-    <property file="${eclipse.pde.dir}/templates/headless-build/build.properties" prefix="pde.template"/>
-    <property name="eclipse.baseos" value="${pde.template.baseos}"/>
-    <property name="eclipse.basews" value="${pde.template.basews}"/>
-    <property name="eclipse.basearch" value="${pde.template.basearch}"/>
-  </target>
-
-  <target name="locateEclipsePDE"
-          if="eclipse.home"
-          description="Locate org.eclipse.pde.build plug-in and set the property 'eclipse.pde.dir'">
-    <first id="eclipse.pde.plugin.dir">
-      <dirset dir="${eclipse.home}/plugins">
-        <include name="org.eclipse.pde.build_*"/>
-      </dirset>
-    </first>
-    <pathconvert property="eclipse.pde.dir" dirsep="/" refid="eclipse.pde.plugin.dir"/>
-  </target>
-
-  <target name="runEclipsePDEBuild">
-    <mkdir dir="${eclipse.projects.dir}/buildScripts/${icu.plugin.id}"/>
-      <copy toDir="${eclipse.projects.dir}/buildScripts/${icu.plugin.id}">
-        <fileset dir="pdebuild" includes="**/*"/>
-          <filterset>
-            <filter token="PLUGIN_ID" value="${icu.plugin.id}"/>
-            <filter token="BUILD_DIR" value="${eclipse.projects.dir.full}"/>
-            <filter token="BUILD_TYPE" value="ICU4J"/>
-            <filter token="BUILD_ID" value="${icu.plugin.id}"/>
-            <filter token="BASE_LOCATION" value="${eclipse.projects.dir.full}/baseLocation"/>
-            <filter token="BASE_OS" value="${eclipse.baseos}"/>
-            <filter token="BASE_WS" value="${eclipse.basews}"/>
-            <filter token="BASE_ARCH" value="${eclipse.basearch}"/>
-            <filter token="JAVA_RT" value="${java.rt}"/>
-          </filterset>
-      </copy>
-
-      <java jar="${eclipse.launcher}" fork="true" failonerror="true">
-        <arg value="-application"/>
-        <arg value="org.eclipse.ant.core.antRunner"/>
-        <arg value="-buildfile"/>
-        <arg value="${eclipse.pde.dir}/scripts/build.xml"/>
-        <arg value="-Dbuilder=${eclipse.projects.dir.full}/buildScripts/${icu.plugin.id}"/>
-      </java>
-  </target>
-
-  <target name="icuProjectFiles"
-        depends="initPluginVersion"
-        description="Copy com.ibm.icu plug-in project files">
-
-    <delete failonerror="no">
-      <fileset dir="${eclipse.projects.dir}/plugins/com.ibm.icu" />
-      <fileset dir="${eclipse.projects.dir}/features/com.ibm.icu" />
-    </delete>
-
-    <!-- icu source -->
-    <copy toDir="${eclipse.projects.dir}/plugins/com.ibm.icu/src">
-      <fileset dir="${icu4j.collate.dir}/src"/>
-      <fileset dir="${icu4j.core.dir}/src"/>
-      <fileset dir="${icu4j.currdata.dir}/src"/>
-      <fileset dir="${icu4j.langdata.dir}/src"/>
-      <fileset dir="${icu4j.regiondata.dir}/src"/>
-      <fileset dir="${icu4j.translit.dir}/src"/>
-    </copy>
-
-    <!-- overwriting the ICU runtime configuration file for forcing ICU4J plugin to use JDK time zone rules -->
-    <copy file="misc/ICUConfig.properties"
-      toDir="${eclipse.projects.dir}/plugins/com.ibm.icu/src/com/ibm/icu"
-      overwrite="true"/>
-
-    <!-- icu data -->
-    <unjar src="${icu4j.data.jar}" dest="${eclipse.projects.dir}/plugins/com.ibm.icu/src">
-      <patternset>
-        <exclude name="META-INF"/>
-        <exclude name="META-INF/**/*"/>
-        <exclude name="**/*.cnv"/>
-        <exclude name="**/cnvalias.icu"/>
-      </patternset>
-    </unjar>
-
-    <!-- icu tz data -->
-    <unjar src="${icu4j.tzdata.jar}" dest="${eclipse.projects.dir}/plugins/com.ibm.icu/src">
-      <patternset>
-        <exclude name="META-INF"/>
-        <exclude name="META-INF/**/*"/>
-      </patternset>
-    </unjar>
-
-    <!-- full locale names lists -->
-    <antcall target="@full-locale-names">
-        <param name="res.dir" value="${eclipse.projects.dir}/plugins/com.ibm.icu/src/${icu4j.data.path}"/>
-    </antcall>
-
-    <antcall target="@full-locale-names">
-        <param name="res.dir" value="${eclipse.projects.dir}/plugins/com.ibm.icu/src/${icu4j.data.path}/brkitr"/>
-    </antcall>
-
-    <antcall target="@full-locale-names">
-        <param name="res.dir" value="${eclipse.projects.dir}/plugins/com.ibm.icu/src/${icu4j.data.path}/coll"/>
-    </antcall>
-
-    <antcall target="@full-locale-names">
-        <param name="res.dir" value="${eclipse.projects.dir}/plugins/com.ibm.icu/src/${icu4j.data.path}/curr"/>
-    </antcall>
-
-    <antcall target="@full-locale-names">
-        <param name="res.dir" value="${eclipse.projects.dir}/plugins/com.ibm.icu/src/${icu4j.data.path}/lang"/>
-    </antcall>
-
-    <antcall target="@full-locale-names">
-        <param name="res.dir" value="${eclipse.projects.dir}/plugins/com.ibm.icu/src/${icu4j.data.path}/rbnf"/>
-    </antcall>
-
-    <antcall target="@full-locale-names">
-        <param name="res.dir" value="${eclipse.projects.dir}/plugins/com.ibm.icu/src/${icu4j.data.path}/region"/>
-    </antcall>
-
-    <antcall target="@full-locale-names">
-        <param name="res.dir" value="${eclipse.projects.dir}/plugins/com.ibm.icu/src/${icu4j.data.path}/translit"/>
-    </antcall>
-
-    <antcall target="@full-locale-names">
-        <param name="res.dir" value="${eclipse.projects.dir}/plugins/com.ibm.icu/src/${icu4j.data.path}/zone"/>
-    </antcall>
-
-    <!-- plugin project -->
-    <copy todir="${eclipse.projects.dir}/plugins/com.ibm.icu">
-      <fileset dir="plugins.template/com.ibm.icu"/>
-      <filterset>
-        <filter token="BUILD_VERSION" value="${icu4j.eclipse.build.version.string}" />
-        <filter token="COPYRIGHT" value="${copyright.eclipse}" />
-        <filter token="IMPL_VERSION" value="${icu4j.impl.version}" />
-        <filter token="DATA_VERSION_NUMBER" value="${icu4j.data.version.number}" />
-      </filterset>
-    </copy>
-
-    <!-- license -->
-    <copy file="${shared.dir}/licenses/LICENSE"
-          todir="${eclipse.projects.dir}/plugins/com.ibm.icu/about_files" />
-
-    <!-- about -->
-    <copy file="misc/about_icu.html"
-          tofile="${eclipse.projects.dir}/plugins/com.ibm.icu/about.html" />
-
-    <!-- FEATURE FILES -->
-    <copy todir="${eclipse.projects.dir}/features/com.ibm.icu">
-      <fileset dir="features.template/com.ibm.icu"/>
-      <filterset>
-        <filter token="BUILD_VERSION" value="${icu4j.eclipse.build.version.string}" />
-        <filter token="COPYRIGHT" value="${copyright.eclipse}" />
-        <filter token="DATA_VERSION_NUMBER" value="${icu4j.data.version.number}" />
-      </filterset>
-    </copy>
-
-  </target>
-
-  <target name="icuTestsProjectFiles"
-        depends="initPluginVersion"
-        description="Copy com.ibm.icu.tests plug-in project files">
-
-    <delete failonerror="no">
-      <fileset dir="${eclipse.projects.dir}/plugins/com.ibm.icu.tests" />
-    </delete>
-
-    <!-- icu test source -->
-    <copy toDir="${eclipse.projects.dir}/plugins/com.ibm.icu.tests/src">
-      <fileset dir="${icu4j.test-framework.dir}/src"/>
-      <fileset dir="${icu4j.core-tests.dir}/src"/>
-      <fileset dir="${icu4j.collate-tests.dir}/src"/>
-      <fileset dir="${icu4j.translit-tests.dir}/src"/>
-    </copy>
-
-    <!-- icu test data -->
-    <unjar src="${icu4j.testdata.jar}" dest="${eclipse.projects.dir}/plugins/com.ibm.icu.tests/src">
-      <patternset>
-        <exclude name="**/*.cnv"/>
-        <exclude name="**/cnvalias.icu"/>
-        <exclude name="META-INF"/>
-        <exclude name="META-INF/**/*"/>
-      </patternset>
-    </unjar>
-
-    <!-- plugin project -->
-    <copy todir="${eclipse.projects.dir}/plugins/com.ibm.icu.tests">
-      <fileset dir="plugins.template/com.ibm.icu.tests"/>
-      <filterset>
-        <filter token="BUILD_VERSION" value="${icu4j.eclipse.build.version.string}" />
-        <filter token="COPYRIGHT" value="${copyright.eclipse}" />
-        <filter token="IMPL_VERSION" value="${icu4j.impl.version}" />
-        <filter token="DATA_VERSION_NUMBER" value="${icu4j.data.version.number}" />
-      </filterset>
-    </copy>
-
-    <!-- license -->
-    <copy file="${shared.dir}/licenses/LICENSE"
-          todir="${eclipse.projects.dir}/plugins/com.ibm.icu.tests/about_files" />
-
-    <!-- about -->
-    <copy file="misc/about_icu.html"
-          tofile="${eclipse.projects.dir}/plugins/com.ibm.icu.tests/about.html" />
-
-  </target>
-
-  <target name="icuBaseProjectFiles"
-        depends="initPluginVersion"
-        description="Copy com.ibm.icu.base plug-in project files">
-
-    <delete failonerror="no">
-      <fileset dir="${eclipse.projects.dir}/plugins/com.ibm.icu.base" />
-      <fileset dir="${eclipse.projects.dir}/features/com.ibm.icu.base" />
-    </delete>
-
-    <!-- plugin project -->
-    <copy todir="${eclipse.projects.dir}/plugins/com.ibm.icu.base">
-      <fileset dir="plugins.template/com.ibm.icu.base"/>
-      <filterset>
-        <filter token="BUILD_VERSION" value="${icu4j.eclipse.build.version.string}" />
-        <filter token="COPYRIGHT" value="${copyright.eclipse}" />
-        <filter token="IMPL_VERSION" value="${icu4j.impl.version}" />
-        <filter token="DATA_VERSION_NUMBER" value="${icu4j.data.version.number}" />
-      </filterset>
-    </copy>
-
-    <!-- license -->
-    <copy file="${shared.dir}/licenses/LICENSE"
-          todir="${eclipse.projects.dir}/plugins/com.ibm.icu.base/about_files" />
-
-    <!-- about -->
-    <copy file="misc/about_icu.html"
-          tofile="${eclipse.projects.dir}/plugins/com.ibm.icu.base/about.html" />
-
-    <!-- FEATURE FILES -->
-    <copy todir="${eclipse.projects.dir}/features/com.ibm.icu.base">
-      <fileset dir="features.template/com.ibm.icu.base"/>
-      <filterset>
-        <filter token="BUILD_VERSION" value="${icu4j.eclipse.build.version.string}" />
-        <filter token="COPYRIGHT" value="${copyright.eclipse}" />
-        <filter token="DATA_VERSION_NUMBER" value="${icu4j.data.version.number}" />
-      </filterset>
-    </copy>
-
-  </target>
-
-  <target name="icuBaseTestsProjectFiles"
-        depends="initPluginVersion"
-        description="Copy com.ibm.icu.base.tests plug-in project files">
-
-    <delete failonerror="no">
-      <fileset dir="${eclipse.projects.dir}/plugins/com.ibm.icu.base.tests" />
-    </delete>
-
-    <!-- plugin project -->
-    <copy todir="${eclipse.projects.dir}/plugins/com.ibm.icu.base.tests">
-      <fileset dir="plugins.template/com.ibm.icu.base.tests"/>
-      <filterset>
-        <filter token="BUILD_VERSION" value="${icu4j.eclipse.build.version.string}" />
-        <filter token="COPYRIGHT" value="${copyright.eclipse}" />
-        <filter token="IMPL_VERSION" value="${icu4j.impl.version}" />
-        <filter token="DATA_VERSION_NUMBER" value="${icu4j.data.version.number}" />
-      </filterset>
-    </copy>
-
-    <!-- license -->
-    <copy file="${shared.dir}/licenses/LICENSE"
-          todir="${eclipse.projects.dir}/plugins/com.ibm.icu.base.tests/about_files" />
-
-    <!-- about -->
-    <copy file="misc/about_icu.html"
-          tofile="${eclipse.projects.dir}/plugins/com.ibm.icu.base.tests/about.html" />
-
-  </target>
-
-</project>
diff --git a/icu4j/eclipse-build/features.template/com.ibm.icu.base/.project b/icu4j/eclipse-build/features.template/com.ibm.icu.base/.project
deleted file mode 100644
index 7f1208b..0000000
--- a/icu4j/eclipse-build/features.template/com.ibm.icu.base/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>com.ibm.icu.base-feature</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.FeatureBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.FeatureNature</nature>
-	</natures>
-</projectDescription>
diff --git a/icu4j/eclipse-build/features.template/com.ibm.icu.base/build.properties b/icu4j/eclipse-build/features.template/com.ibm.icu.base/build.properties
deleted file mode 100644
index c6c3b4d..0000000
--- a/icu4j/eclipse-build/features.template/com.ibm.icu.base/build.properties
+++ /dev/null
@@ -1,20 +0,0 @@
-###############################################################################
-# Copyright (c) 2011,2016 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     IBM Corporation - initial API and implementation
-###############################################################################
-bin.includes =\
-epl-v10.html,\
-eclipse_update_120.jpg,\
-feature.xml,\
-feature.properties,\
-LICENSE
-outputUpdateJars = true
-
-generate.plugin@com.ibm.icu.base.source=com.ibm.icu.base
-
diff --git a/icu4j/eclipse-build/features.template/com.ibm.icu.base/feature.xml b/icu4j/eclipse-build/features.template/com.ibm.icu.base/feature.xml
deleted file mode 100644
index 5102e29..0000000
--- a/icu4j/eclipse-build/features.template/com.ibm.icu.base/feature.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feature
-      id="com.ibm.icu.base"
-      label="com.ibm.icu.base"
-      version="@BUILD_VERSION@">
-
-   <description url="http://www.example.com/description">
-      [Enter Feature Description here.]
-   </description>
-
-   <copyright url="http://www.example.com/copyright">
-      [Enter Copyright Description here.]
-   </copyright>
-
-   <license url="http://www.example.com/license">
-      [Enter License Description here.]
-   </license>
-
-   <plugin
-         id="com.ibm.icu.base"
-         download-size="0"
-         install-size="0"
-         version="@BUILD_VERSION@"
-         unpack="false"/>
-
-   <plugin
-         id="com.ibm.icu.base.source"
-         download-size="0"
-         install-size="0"
-         version="@BUILD_VERSION@"
-         unpack="false"/>
-
-</feature>
diff --git a/icu4j/eclipse-build/features.template/com.ibm.icu/.project b/icu4j/eclipse-build/features.template/com.ibm.icu/.project
deleted file mode 100644
index d407fa0..0000000
--- a/icu4j/eclipse-build/features.template/com.ibm.icu/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>com.ibm.icu-feature</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.FeatureBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.FeatureNature</nature>
-	</natures>
-</projectDescription>
diff --git a/icu4j/eclipse-build/features.template/com.ibm.icu/build.properties b/icu4j/eclipse-build/features.template/com.ibm.icu/build.properties
deleted file mode 100644
index bec15cf..0000000
--- a/icu4j/eclipse-build/features.template/com.ibm.icu/build.properties
+++ /dev/null
@@ -1,20 +0,0 @@
-###############################################################################
-# Copyright (c) 2000,2016 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     IBM Corporation - initial API and implementation
-###############################################################################
-bin.includes =\
-epl-v10.html,\
-eclipse_update_120.jpg,\
-feature.xml,\
-feature.properties,\
-LICENSE
-outputUpdateJars = true
-
-generate.plugin@com.ibm.icu.source=com.ibm.icu
-
diff --git a/icu4j/eclipse-build/features.template/com.ibm.icu/feature.xml b/icu4j/eclipse-build/features.template/com.ibm.icu/feature.xml
deleted file mode 100644
index 417e65b..0000000
--- a/icu4j/eclipse-build/features.template/com.ibm.icu/feature.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feature
-      id="com.ibm.icu"
-      label="com.ibm.icu"
-      version="@BUILD_VERSION@">
-
-   <description url="http://www.example.com/description">
-      [Enter Feature Description here.]
-   </description>
-
-   <copyright url="http://www.example.com/copyright">
-      [Enter Copyright Description here.]
-   </copyright>
-
-   <license url="http://www.example.com/license">
-      [Enter License Description here.]
-   </license>
-
-   <plugin
-         id="com.ibm.icu"
-         download-size="0"
-         install-size="0"
-         version="@BUILD_VERSION@"
-         unpack="false"/>
-
-   <plugin
-         id="com.ibm.icu.source"
-         download-size="0"
-         install-size="0"
-         version="@BUILD_VERSION@"
-         unpack="false"/>
-
-</feature>
diff --git a/icu4j/eclipse-build/misc/ICUConfig.properties b/icu4j/eclipse-build/misc/ICUConfig.properties
deleted file mode 100644
index 1b88ef3..0000000
--- a/icu4j/eclipse-build/misc/ICUConfig.properties
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2016 and later: Unicode, Inc. and others.
-# License & terms of use: http://www.unicode.org/copyright.html
-#*******************************************************************************
-#* Copyright (C) 2008-2011, International Business Machines Corporation and    *
-#* others. All Rights Reserved.                                                *
-#*******************************************************************************
-#* This is the properties contains ICU runtime configuration 
-#*
-
-#
-# The default TimeZone implementation type used by the ICU TimeZone
-# factory method. [ ICU | JDK ]
-#
-com.ibm.icu.util.TimeZone.DefaultTimeZoneType = JDK
-
-#
-# By default, DecimalFormat uses some internal equivalent character
-# data in addition to ones in DecimalFormatSymbols for parsing
-# decimal/grouping separators.  When this property is true,
-# DecimalFormat uses separators configured by DecimalFormatSymbols only
-# and does not try to find a match in the internal equivalent character
-# data.
-#
-com.ibm.icu.text.DecimalFormat.SkipExtendedSeparatorParsing = false
-
-
-# 
-# [Internal Use Only]
-# Disable resource path scan for building full locale name list
-# at run time.
-#
-com.ibm.icu.impl.ICUResourceBundle.skipRuntimeLocaleResourceScan = false
diff --git a/icu4j/eclipse-build/misc/about_icu.html b/icu4j/eclipse-build/misc/about_icu.html
deleted file mode 100644
index 2fa9ccc..0000000
--- a/icu4j/eclipse-build/misc/about_icu.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-<meta name="COPYRIGHT" content="© 2016 and later: Unicode, Inc. and others. License & terms of use: http://www.unicode.org/copyright.html">
-<title>About com.ibm.icu plugin</title>
-</head>
-<body lang="EN-US">
-<h2>About This Content</h2>
- 
-<p>Sept 18, 2018</p>
-<h3>License</h3>
-
-<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
-indicated below, the Content is provided to you under the terms and conditions of the
-Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
-at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
-For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
-
-<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
-being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
-apply to your use of any object code in the Content.  Check the Redistributor's license that was 
-provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
-indicated below, the terms and conditions of the EPL still apply to any source code in the Content
-and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
-
-
-<h3>Third Party Content</h3>
-<p>The Content includes items that have been sourced from third parties as set out below. If you 
-did not receive this Content directly from the Eclipse Foundation, the following is provided 
-for informational purposes only, and you should look to the Redistributor's license for 
-terms and conditions of use.</p>
-
-<p><strong>ICU4J 63.1.0 plug-in</strong></p>
-
-<p>The plug-in includes software (&quot;ICU4J&quot;) developed by Unicode Inc. and others.
-Your use of ICU4J is subject to the terms and conditions of the ICU license.  A copy of the
-license is contained in the file <a href="about_files/LICENSE" target="_blank">about_files/LICENSE</a>.</p>
-
-<p>The project information including source code, documentations and demo programs are available on
-the <a href="http://www.icu-project.org">ICU public web site</a>.</p>
-
-</body>
-</html>
diff --git a/icu4j/eclipse-build/misc/about_icu_base.html b/icu4j/eclipse-build/misc/about_icu_base.html
deleted file mode 100644
index aceb93f..0000000
--- a/icu4j/eclipse-build/misc/about_icu_base.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-<meta name="COPYRIGHT" content="© 2016 and later: Unicode, Inc. and others. License & terms of use: http://www.unicode.org/copyright.html">
-<title>About com.ibm.icu.base plugin</title>
-</head>
-<body lang="EN-US">
-<h2>About This Content</h2>
- 
-<p>Sept 18, 2018</p>
-<h3>License</h3>
-
-<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
-indicated below, the Content is provided to you under the terms and conditions of the
-Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
-at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
-For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
-
-<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
-being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
-apply to your use of any object code in the Content.  Check the Redistributor's license that was 
-provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
-indicated below, the terms and conditions of the EPL still apply to any source code in the Content
-and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
-
-
-<h3>Third Party Content</h3>
-<p>The Content includes items that have been sourced from third parties as set out below. If you 
-did not receive this Content directly from the Eclipse Foundation, the following is provided 
-for informational purposes only, and you should look to the Redistributor's license for 
-terms and conditions of use.</p>
-
-<p><strong>ICU4J 63.1.0 base plug-in</strong></p>
-
-<p>The plug-in includes software (&quot;ICU4J&quot;) developed by Unicode Inc. and others.
-Your use of ICU4J is subject to the terms and conditions of the ICU license.  A copy of the
-license is contained in the file <a href="about_files/LICENSE" target="_blank">about_files/LICENSE</a>.</p>
-
-<p>The project information including source code, documentations and demo programs are available on
-the <a href="http://www.icu-project.org">ICU public web site</a>.</p>
-
-</body>
-</html>
diff --git a/icu4j/eclipse-build/pdebuild/allElements.xml b/icu4j/eclipse-build/pdebuild/allElements.xml
deleted file mode 100644
index e4d6613..0000000
--- a/icu4j/eclipse-build/pdebuild/allElements.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<project name="allElements Delegator">
-	
- 	<!-- ===================================================================== -->
- 	<!-- Run a given ${target} on all elements being built                     -->
- 	<!-- Replace element.id with the id of the top level element being built.    -->
-	<!-- If element.id does not exist in ${buildDirectory}/features/element.id   -->
-	<!-- or ${baseLocation}/features/element.id, then you must provide the       -->
-	<!-- location by setting the property "pluginPath"                           -->
- 	<!-- Add on <ant> task for each top level element being built.             -->
- 	<!-- ===================================================================== -->
- 	<target name="allElementsDelegator">
- 		<ant antfile="${genericTargets}" target="${target}">
-	 		<property name="type" value="feature" />
-	 		<property name="id" value="@PLUGIN_ID@" />
- 		</ant>
- 	</target>
- 
- 	<!-- ===================================================================== -->
- 	<!-- Targets to assemble the built elements for particular configurations  -->
- 	<!-- These generally call the generated assemble scripts (named in         -->
- 	<!-- ${assembleScriptName}) but may also add pre and post processing       -->
- 	<!-- Add one target for each root element and each configuration           -->
- 	<!-- Replace element.id with the id of the top level element being built   -->
- 	<!-- ===================================================================== -->
- 	<target name="assemble.@PLUGIN_ID@">
- 		<ant antfile="${assembleScriptName}" dir="${buildDirectory}"/>
- 	</target>
-</project>
diff --git a/icu4j/eclipse-build/pdebuild/build.properties b/icu4j/eclipse-build/pdebuild/build.properties
deleted file mode 100644
index 00b3b3d..0000000
--- a/icu4j/eclipse-build/pdebuild/build.properties
+++ /dev/null
@@ -1,224 +0,0 @@
-###############################################################################
-# Copyright (C) 2016 and later: Unicode, Inc. and others.
-# License & terms of use: http://www.unicode.org/copyright.html
-# Copyright (c) 2003-2015 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     IBM Corporation - initial API and implementation
-###############################################################################
-#####################
-# Parameters describing how and where to execute the build.
-# Typical users need only update the following properties:
-#    baseLocation - where things you are building against are installed
-#    bootclasspath - The base jars to compile against (typicaly rt.jar)
-#    configs - the list of {os, ws, arch} configurations to build.  
-#
-# Of course any of the settings here can be overridden by spec'ing 
-# them on the command line (e.g., -DbaseLocation=d:/eclipse
-
-############# PRODUCT/PACKAGING CONTROL #############
-product=/plugin or feature id/path/to/.product
-runPackager=true
-
-#Set the name of the archive that will result from the product build.
-#archiveNamePrefix=
-
-# The prefix that will be used in the generated archive.
-#archivePrefix=<output archive root>
-archivePrefix=
-
-# The location underwhich all of the build output will be collected.
-collectingFolder=${archivePrefix}
-
-# The list of {os, ws, arch} configurations to build.  This 
-# value is a '&' separated list of ',' separate triples.  For example, 
-#     configs=win32,win32,x86 & linux,motif,x86
-# By default the value is *,*,*
-#configs=win32, win32, x86 & \
-#	linux, gtk, ppc &\
-# linux, gtk, x86 & \
-#	linux, gtk, x86_64 & \
-#	linux, motif, x86 & \
-#	solaris, motif, sparc & \
-#	solaris, gtk, sparc & \
-#	aix, motif, ppc & \
-#	hpux, motif, PA_RISC & \
-#	macosx, carbon, ppc
-
-# By default PDE creates one archive (result) per entry listed in the configs property.
-# Setting this value to try will cause PDE to only create one output containing all 
-# artifacts for all the platforms listed in the configs property.
-#groupConfigurations=true
-
-#The format of the archive. By default a zip is created using antZip.
-#The list can only contain the configuration for which the desired format is different than zip.
-#archivesFormat=win32, win32, x86 - antZip& \
-#	linux, gtk, ppc - antZip &\
-#    linux, gtk, x86 - antZip& \
-#	linux, gtk, x86_64 - antZip& \
-# linux, motif, x86 - antZip& \
-#	solaris, motif, sparc - antZip& \
-#	solaris, gtk, sparc - antZip& \
-#	aix, motif, ppc - antZip& \
-#	hpux, motif, PA_RISC - antZip& \
-#	macosx, carbon, ppc - antZip
-	
-#Set to true if you want the output to be ready for an update jar (no site.xml generated)
-#outputUpdateJars = false
-
-#Set to true for Jnlp generation
-#codebase should be a URL that will be used as the root of all relative URLs in the output.
-#generateJnlp=false
-#jnlp.codebase=<codebase url>
-#jnlp.j2se=<j2se version>
-#jnlp.locale=<a locale>
-
-#Set to true if you want to sign jars
-#signJars=false
-#sign.alias=<alias>
-#sign.keystore=<keystore location>
-#sign.storepass=<keystore password>
-
-#Arguments to send to the zip executable
-zipargs=
-
-#Arguments to send to the tar executable
-tarargs=
-
-#Control the creation of a file containing the version included in each configuration - on by default 
-#generateVersionsLists=false
-
-############## BUILD NAMING CONTROL ################
-# The directory into which the build elements are fetched and where
-# the build takes place.
-buildDirectory=@BUILD_DIR@
-
-# Type of build.  Used in naming the build output.  Typically this value is
-# one of I, N, M, S, ...
-buildType=@BUILD_TYPE@
-
-# ID of the build.  Used in naming the build output.
-buildId=@BUILD_ID@
-
-# Label for the build.  Used in naming the build output
-buildLabel=${buildType}.${buildId}
-
-# Timestamp for the build.  Used in naming the build output
-timestamp=007
-
-#The value to be used for the qualifier of a plugin or feature when you want to override the value computed by pde.
-#The value will only be applied to plugin or features indicating build.properties, qualifier = context 
-#forceContextQualifier=<the value for the qualifier>
-
-#Enable / disable the generation of a suffix for the features that use .qualifier. 
-#The generated suffix is computed according to the content of the feature   
-#generateFeatureVersionSuffix=true
-
-############# BASE CONTROL #############
-# Settings for the base Eclipse components and Java class libraries 
-# against which you are building.
-# Base location for anything the build needs to compile against.  For example,
-# in most RCP app or a plug-in,  the baseLocation should be the location of a previously
-# installed Eclipse against which the application or plug-in code will be compiled and the RCP delta pack.
-
-base=<path/to/parent/of/eclipse>
-#baseLocation=${base}/eclipse
-baseLocation=@BASE_LOCATION@
-#Os/Ws/Arch/nl of the eclipse specified by baseLocation
-baseos=@BASE_OS@
-basews=@BASE_WS@
-basearch=@BASE_ARCH@
-
-#this property indicates whether you want the set of plug-ins and features to be considered during the build to be limited to the ones reachable from the features / plugins being built
-filteredDependencyCheck=false
-
-#pluginPath is a list of locations in which to find plugins and features.  This list is separated by the platform file separator (; or :)
-#a location is one of:  
-#- the location of the jar or folder that is the plugin or feature : /path/to/foo.jar or /path/to/foo
-#- a directory that contains a /plugins or /features subdirectory
-#- the location of a feature.xml, or for 2.1 style plugins, the plugin.xml or fragment.xml
-#pluginPath=
-
-skipBase=true
-eclipseURL=<url for eclipse download site>
-eclipseBuildId=<Id of Eclipse build to get>
-eclipseBaseURL=${eclipseURL}/eclipse-platform-${eclipseBuildId}-win32.zip
-
-
-############# MAP FILE CONTROL ################
-# This section defines CVS tags to use when fetching the map files from the repository.
-# If you want to fetch the map file from repository / location, change the getMapFiles target in the customTargets.xml
-
-skipMaps=true
-mapsRepo=:pserver:anonymous@example.com/path/to/repo
-mapsRoot=path/to/maps
-mapsCheckoutTag=HEAD
-
-#tagMaps=true
-mapsTagTag=v${buildId}
-
-
-############ REPOSITORY CONTROL ###############
-# This section defines properties parameterizing the repositories where plugins, fragments
-# bundles and features are being obtained from. 
-
-# The tags to use when fetching elements to build.
-# By default thebuilder will use whatever is in the maps.  
-# This value takes the form of a comma separated list of repository identifier (like used in the map files) and the 
-# overriding value
-# For example fetchTag=CVS=HEAD, SVN=v20050101
-# fetchTag=HEAD
-skipFetch=true
-
-
-############# JAVA COMPILER OPTIONS ##############
-# The location of the Java jars to compile against.  Typically the rt.jar for your JDK/JRE
-#bootclasspath=${java.home}/lib/rt.jar
-
-# specific JRE locations to compile against. These values are used to compile bundles specifying a 
-# Bundle-RequiredExecutionEnvironment. Uncomment and set values for environments that you support
-#CDC-1.0/Foundation-1.0= /path/to/rt.jar
-#CDC-1.1/Foundation-1.1=
-#OSGi/Minimum-1.0=
-#OSGi/Minimum-1.1=
-#JRE-1.1=
-#J2SE-1.2=
-#J2SE-1.3=
-#J2SE-1.4=
-#J2SE-1.5=
-#JavaSE-1.6=
-#JavaSE-1.7=
-JavaSE-1.7=@JAVA_RT@
-#PersonalJava-1.1=
-#PersonalJava-1.2=
-#CDC-1.0/PersonalBasis-1.0=
-#CDC-1.0/PersonalJava-1.0=
-#CDC-1.1/PersonalBasis-1.1=
-#CDC-1.1/PersonalJava-1.1=
-
-# Specify the output format of the compiler log when eclipse jdt is used
-logExtension=.log
-
-# Whether or not to include debug info in the output jars
-javacDebugInfo=true
-
-# Whether or not to fail the build if there are compiler errors
-javacFailOnError=true
-
-# Enable or disable verbose mode of the compiler
-javacVerbose=true
-
-# Extra arguments for the compiler. These are specific to the java compiler being used.
-compilerArg=-inlineJSR -enableJavadoc -encoding UTF-8
-
-# Default value for the version of the source code. This value is used when compiling plug-ins that do not set the Bundle-RequiredExecutionEnvironment or set javacSource in build.properties
-javacSource=1.7
-
-# Default value for the version of the byte code targeted. This value is used when compiling plug-ins that do not set the Bundle-RequiredExecutionEnvironment or set javacTarget in build.properties.
-javacTarget=1.7
-
-individualSourceBundles=true
diff --git a/icu4j/eclipse-build/pdebuild/customTargets.xml b/icu4j/eclipse-build/pdebuild/customTargets.xml
deleted file mode 100644
index ae4266d..0000000
--- a/icu4j/eclipse-build/pdebuild/customTargets.xml
+++ /dev/null
@@ -1,161 +0,0 @@
-<project name="Build specific targets and properties" default="noDefault">
-
-	<!-- ===================================================================== -->
-	<!-- Run a given ${target} on all elements being built -->
-	<!-- Add on <ant> task for each top level element being built. -->
-	<!-- ===================================================================== -->
-	<property name="allElementsFile" value="${builder}/allElements.xml"/>
-	<import file="${allElementsFile}" />
-	<target name="allElements">
-		<antcall target="allElementsDelegator" />
-	</target>
-	
-	<!-- ===================================================================== -->
-	<!-- ===================================================================== -->
-	<target name="getBaseComponents" depends="checkLocalBase" unless="skipBase">
-		<get src="${eclipseBaseURL}" dest="${buildDirectory}/../temp-base.zip" />
-		<unzip dest="${base}" overwrite="true" src="${buildDirectory}/../temp-base.zip" />
-	</target>
-
-	<target name="checkLocalBase">
-		<available file="${base}" property="skipBase" />
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Check out map files from correct repository -->
-	<!-- Replace values for mapsCheckoutTag as desired. -->
-	<!-- ===================================================================== -->
-	<target name="getMapFiles" depends="checkLocalMaps" unless="skipMaps">
-		<property name="mapsCheckoutTag" value="HEAD" />
-		<cvs cvsRoot="${mapsRepo}" package="${mapsRoot}" dest="${buildDirectory}/maps" tag="${mapsCheckoutTag}" />
-	</target>
-
-	<target name="checkLocalMaps">
-		<available property="skipMaps" file="${buildDirectory}/maps" />
-	</target>
-
-	<target name="tagMapFiles" if="tagMaps">
-		<cvs dest="${buildDirectory}/maps/${mapsRoot}" command="tag ${mapsTagTag}" />
-	</target>
-
-	<!-- ===================================================================== -->
-
-	<target name="clean" unless="noclean">
-		<antcall target="allElements">
-			<param name="target" value="cleanElement" />
-		</antcall>
-	</target>
-
-	<target name="gatherLogs">
-		<mkdir dir="${buildDirectory}/${buildLabel}/compilelogs" />
-		<antcall target="allElements">
-			<param name="target" value="gatherLogs" />
-		</antcall>
-		<unzip dest="${buildDirectory}/${buildLabel}/compilelogs" overwrite="true">
-			<fileset dir="${buildDirectory}/features">
-				<include name="**/*.log.zip" />
-			</fileset>
-		</unzip>
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Steps to do before setup -->
-	<!-- ===================================================================== -->
-	<target name="preSetup">
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Steps to do after setup but before starting the build proper -->
-	<!-- ===================================================================== -->
-	<target name="postSetup">
-		<antcall target="getBaseComponents" />
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Steps to do before fetching the build elements -->
-	<!-- ===================================================================== -->
-	<target name="preFetch">
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Steps to do after fetching the build elements -->
-	<!-- ===================================================================== -->
-	<target name="postFetch">
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Steps to do before generating the build scripts. -->
-	<!-- ===================================================================== -->
-	<target name="preGenerate">
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Steps to do after generating the build scripts. -->
-	<!-- ===================================================================== -->
-	<target name="postGenerate">
-		<antcall target="clean" />
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Steps to do before running the build.xmls for the elements being built. -->
-	<!-- ===================================================================== -->
-	<target name="preProcess">
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Steps to do after running the build.xmls for the elements being built. -->
-	<!-- ===================================================================== -->
-	<target name="postProcess">
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Steps to do before running assemble. -->
-	<!-- ===================================================================== -->
-	<target name="preAssemble">
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Steps to do after  running assemble. -->
-	<!-- ===================================================================== -->
-	<target name="postAssemble">
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Steps to do before running package. -->
-	<!-- ===================================================================== -->
-	<target name="prePackage">
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Steps to do after  running package. -->
-	<!-- ===================================================================== -->
-	<target name="postPackage">
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Steps to do after the build is done. -->
-	<!-- ===================================================================== -->
-	<target name="postBuild">
-		<antcall target="gatherLogs" />
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Steps to do to test the build results -->
-	<!-- ===================================================================== -->
-	<target name="test">
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Steps to do to publish the build results -->
-	<!-- ===================================================================== -->
-	<target name="publish">
-	</target>
-
-	<!-- ===================================================================== -->
-	<!-- Default target                                                        -->
-	<!-- ===================================================================== -->
-	<target name="noDefault">
-		<echo message="You must specify a target when invoking this file" />
-	</target>
-
-</project>
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.classpath b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.classpath
deleted file mode 100644
index 3bc2475..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.project b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.project
deleted file mode 100644
index 848567c..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.project
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>com.ibm.icu.base.tests</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.ManifestBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.SchemaBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.PluginNature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.settings/org.eclipse.core.resources.prefs b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c0..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/<project>=UTF-8
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.settings/org.eclipse.jdt.core.prefs b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index b237e4c..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,77 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=ignore
-org.eclipse.jdt.core.compiler.problem.deprecation=ignore
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=warning
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.7
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.settings/org.eclipse.jdt.ui.prefs b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.settings/org.eclipse.jdt.ui.prefs
deleted file mode 100644
index 1c69cb6..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/.settings/org.eclipse.jdt.ui.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Thu Dec 14 11:51:01 EST 2006
-eclipse.preferences.version=1
-internal.default.compliance=default
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/META-INF/MANIFEST.MF b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/META-INF/MANIFEST.MF
deleted file mode 100644
index b473e18..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,10 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: %pluginName
-Bundle-SymbolicName: com.ibm.icu.base.tests
-Bundle-Version: @BUILD_VERSION@
-Bundle-Vendor: %providerName
-Fragment-Host: com.ibm.icu.base
-Bundle-Copyright: @COPYRIGHT@
-Require-Bundle: org.junit
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/build.properties b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/build.properties
deleted file mode 100644
index 3edb708..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/build.properties
+++ /dev/null
@@ -1,17 +0,0 @@
-###############################################################################
-# Copyright (c) 2000, 2011 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     IBM Corporation - initial API and implementation
-###############################################################################
-source.. = src/
-output.. = bin/
-bin.includes = .,\
-               about.html,\
-               about_files/,\
-               plugin.properties,\
-               META-INF/
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/plugin.properties b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/plugin.properties
deleted file mode 100644
index 5038ce3..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/plugin.properties
+++ /dev/null
@@ -1,12 +0,0 @@
-###############################################################################
-# Copyright (c) 2011 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials 
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     IBM Corporation - initial API and implementation
-###############################################################################
-pluginName = International Components for Unicode for Java (ICU4J) Replacement plug-in Tests
-providerName = IBM Corporation
\ No newline at end of file
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/BreakIteratorTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/BreakIteratorTest.java
deleted file mode 100644
index 1ddd5d8..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/BreakIteratorTest.java
+++ /dev/null
@@ -1,361 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2006-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.tests;
-
-import java.text.CharacterIterator;
-import java.text.StringCharacterIterator;
-import java.util.Locale;
-
-import com.ibm.icu.text.BreakIterator;
-import com.ibm.icu.util.ULocale;
-
-public class BreakIteratorTest extends ICUTestCase {
-    // ICU behaves a bit differently with this text, but the tested values aren't
-    // affected.  If Java changes behavior they might need to change.
-    private static final String text = "Mr. and Mrs. Mumblety-Peg paid $35.97 for a new 12\" cockatoo. " +
-        "When they got home they both cooed \"Isn't it lovely?\" and sighed softly. " +
-        "\"Let's name it u\u0308\u5098!\" they said with glee.";
-    private static int pos = text.indexOf("sn't");
-    private static BreakIterator cbr;
-    private static BreakIterator wbr;
-    private static BreakIterator lbr;
-    private static BreakIterator sbr;
-        
-    static {
-        cbr = BreakIterator.getCharacterInstance();
-        cbr.setText(text);
-        wbr = BreakIterator.getWordInstance();
-        wbr.setText(text);
-        lbr = BreakIterator.getLineInstance();
-        lbr.setText(text);
-        sbr = BreakIterator.getSentenceInstance();
-        sbr.setText(text);
-                
-        // diagnostic
-        //              dump(cbr);
-        //              dump(wbr);
-        //              dump(lbr);
-        //              dump(sbr);
-    }
-        
-    //      private static void dump(BreakIterator bi) {
-    //              for (int ix = bi.first(), lim = text.length(); ix != lim;) {
-    //                      int nx = bi.next();
-    //                      if (nx < 0) nx = lim;
-    //                      System.out.println(Integer.toString(ix) + ": " + text.substring(ix, nx));
-    //                      ix = nx;
-    //              }
-    //      }
-        
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.hashCode()'
-     */
-    public void testHashCode() {
-        BreakIterator br = BreakIterator.getWordInstance();
-        br.setText(text);
-        BreakIterator brne = BreakIterator.getWordInstance();
-        brne.setText(text + "X");
-        wbr.first();
-        testEHCS(br, wbr, brne);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.BreakIterator(BreakIterator)'
-     */
-    public void testBreakIterator() {
-        // implicitly tested everywhere
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.first()'
-     */
-    public void testFirst() {
-        assertEquals(0, cbr.first());
-        assertEquals(0, wbr.first());
-        assertEquals(0, lbr.first());
-        assertEquals(0, sbr.first());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.last()'
-     */
-    public void testLast() {
-        assertEquals(text.length(), cbr.last());
-        assertEquals(text.length(), wbr.last());
-        assertEquals(text.length(), lbr.last());
-        assertEquals(text.length(), sbr.last());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.next(int)'
-     */
-    public void testNextInt() {
-        cbr.first();
-        wbr.first();
-        lbr.first();
-        sbr.first();
-        assertEquals(2, cbr.next(2));
-        assertEquals(3, wbr.next(2));
-        assertEquals(8, lbr.next(2));
-        assertEquals(62, sbr.next(2));
-                
-        cbr.last();
-        wbr.last();
-        lbr.last();
-        sbr.last();
-        assertEquals(174, cbr.next(-2));
-        assertEquals(171, wbr.next(-2));
-        assertEquals(166, lbr.next(-2));
-        assertEquals(135, sbr.next(-2));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.next()'
-     */
-    public void testNext() {
-        cbr.first();
-        wbr.first();
-        lbr.first();
-        sbr.first();
-        assertEquals(1, cbr.next());
-        assertEquals(2, wbr.next());
-        assertEquals(4, lbr.next());
-        assertEquals(13, sbr.next());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.previous()'
-     */
-    public void testPrevious() {
-        cbr.last();
-        wbr.last();
-        lbr.last();
-        sbr.last();
-        assertEquals(175, cbr.previous());
-        assertEquals(175, wbr.previous());
-        assertEquals(171, lbr.previous());
-        assertEquals(156, sbr.previous());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.following(int)'
-     */
-    public void testFollowing() {
-        assertEquals(100, cbr.following(pos));
-        assertEquals(103, wbr.following(pos));
-        assertEquals(104, lbr.following(pos));
-        assertEquals(116, sbr.following(pos));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.preceding(int)'
-     */
-    public void testPreceding() {
-        assertEquals(98, cbr.preceding(pos));
-        assertEquals(98, wbr.preceding(pos));
-        assertEquals(97, lbr.preceding(pos));
-        assertEquals(62, sbr.preceding(pos));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.isBoundary(int)'
-     */
-    public void testIsBoundary() {
-        assertTrue(cbr.isBoundary(pos));
-        assertFalse(wbr.isBoundary(pos));
-        assertFalse(lbr.isBoundary(pos));
-        assertFalse(sbr.isBoundary(pos));
-
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.current()'
-     */
-    public void testCurrent() {
-        cbr.following(pos);
-        wbr.following(pos);
-        lbr.following(pos);
-        sbr.following(pos);
-        assertEquals(100, cbr.current());
-        assertEquals(103, wbr.current());
-        assertEquals(104, lbr.current());
-        assertEquals(116, sbr.current());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getText()'
-     */
-    public void testGetText() {
-        CharacterIterator ci = cbr.getText();
-        StringBuffer buf = new StringBuffer(ci.getEndIndex() - ci.getBeginIndex());
-        for (char c = ci.first(); c != CharacterIterator.DONE; c = ci.next()) {
-            buf.append(c);
-        }
-        String result = buf.toString();
-        assertEquals(text, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.setText(String)'
-     */
-    public void testSetTextString() {
-        // implicitly tested
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.setText(CharacterIterator)'
-     */
-    public void testSetTextCharacterIterator() {
-        CharacterIterator ci = new StringCharacterIterator(text, pos);
-        BreakIterator bi = BreakIterator.getWordInstance();
-        bi.setText(ci);
-        assertEquals(2, bi.next());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getWordInstance()'
-     */
-    public void testGetWordInstance() {
-        // implicitly tested
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getWordInstance(Locale)'
-     */
-    public void testGetWordInstanceLocale() {
-        assertNotNull(BreakIterator.getWordInstance(Locale.JAPAN));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getWordInstance(ULocale)'
-     */
-    public void testGetWordInstanceULocale() {
-        assertNotNull(BreakIterator.getWordInstance(ULocale.JAPAN));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getLineInstance()'
-     */
-    public void testGetLineInstance() {
-        // implicitly tested
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getLineInstance(Locale)'
-     */
-    public void testGetLineInstanceLocale() {
-        assertNotNull(BreakIterator.getLineInstance(Locale.JAPAN));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getLineInstance(ULocale)'
-     */
-    public void testGetLineInstanceULocale() {
-        assertNotNull(BreakIterator.getLineInstance(ULocale.JAPAN));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getCharacterInstance()'
-     */
-    public void testGetCharacterInstance() {
-        // implicitly tested
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getCharacterInstance(Locale)'
-     */
-    public void testGetCharacterInstanceLocale() {
-        assertNotNull(BreakIterator.getCharacterInstance(Locale.JAPAN));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getCharacterInstance(ULocale)'
-     */
-    public void testGetCharacterInstanceULocale() {
-        assertNotNull(BreakIterator.getCharacterInstance(ULocale.JAPAN));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getSentenceInstance()'
-     */
-    public void testGetSentenceInstance() {
-        // implicitly tested
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getSentenceInstance(Locale)'
-     */
-    public void testGetSentenceInstanceLocale() {
-        assertNotNull(BreakIterator.getSentenceInstance(Locale.JAPAN));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getSentenceInstance(ULocale)'
-     */
-    public void testGetSentenceInstanceULocale() {
-        assertNotNull(BreakIterator.getSentenceInstance(ULocale.JAPAN));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getTitleInstance()'
-     */
-    public void testGetTitleInstance() {
-        // not implemented
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getTitleInstance(Locale)'
-     */
-    public void testGetTitleInstanceLocale() {
-        // not implemented
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getTitleInstance(ULocale)'
-     */
-    public void testGetTitleInstanceULocale() {
-        // not implemented
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getAvailableLocales()'
-     */
-    public void testGetAvailableLocales() {
-        assertNotNull(BreakIterator.getAvailableLocales());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.getAvailableULocales()'
-     */
-    public void testGetAvailableULocales() {
-        assertNotNull(BreakIterator.getAvailableULocales());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.toString()'
-     */
-    public void testToString() {
-        assertNotNull(cbr.toString());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.clone()'
-     */
-    public void testClone() {
-        // see testHashCode
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.BreakIterator.equals(Object)'
-     */
-    public void testEqualsObject() {
-        // see testHashCode
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CalendarTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CalendarTest.java
deleted file mode 100644
index 9b0e755..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CalendarTest.java
+++ /dev/null
@@ -1,553 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2006-2012, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.tests;
-
-import java.util.Date;
-import java.util.Locale;
-
-import com.ibm.icu.text.DateFormat;
-import com.ibm.icu.util.Calendar;
-import com.ibm.icu.util.TimeZone;
-import com.ibm.icu.util.ULocale;
-
-public class CalendarTest extends ICUTestCase {
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.hashCode()'
-     */
-    public void testHashCode() {
-        Calendar cal1 = Calendar.getInstance();
-        Calendar cal2 = Calendar.getInstance();
-        Calendar cal3 = Calendar.getInstance();
-
-        long t = System.currentTimeMillis();
-        cal1.setTimeInMillis(t);
-        cal2.setTimeInMillis(t);
-        cal3.setTimeInMillis(t);
-
-        cal3.setMinimalDaysInFirstWeek(cal3.getMinimalDaysInFirstWeek()+1);
-        testEHCS(cal1, cal2, cal3);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.Calendar(Calendar)'
-     */
-    public void testCalendar() {
-        // tested implicitly everywhere
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getInstance()'
-     */
-    public void testGetInstance() {
-        // tested by testEHCS
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getInstance(TimeZone)'
-     */
-    public void testGetInstanceTimeZone() {
-        TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
-        Calendar cal = Calendar.getInstance(tz);
-        assertNotNull(cal);
-        assertNotNull(cal.getTime());
-        assertEquals(tz, cal.getTimeZone());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getInstance(Locale)'
-     */
-    public void testGetInstanceLocale() {
-        Calendar cal = Calendar.getInstance(Locale.US);
-        assertNotNull(cal);
-        assertNotNull(cal.getTime());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getInstance(ULocale)'
-     */
-    public void testGetInstanceULocale() {
-        Calendar cal = Calendar.getInstance(ULocale.US);
-        assertNotNull(cal);
-        assertNotNull(cal.getTime());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getInstance(TimeZone, Locale)'
-     */
-    public void testGetInstanceTimeZoneLocale() {
-        TimeZone tz = TimeZone.getTimeZone("America/New_York");
-        Calendar cal = Calendar.getInstance(tz, Locale.US);
-        assertNotNull(cal);
-        assertNotNull(cal.getTime());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getInstance(TimeZone, ULocale)'
-     */
-    public void testGetInstanceTimeZoneULocale() {
-        TimeZone tz = TimeZone.getTimeZone("America/New_York");
-        Calendar cal = Calendar.getInstance(tz, ULocale.US);
-        assertNotNull(cal);
-        assertNotNull(cal.getTime());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getAvailableLocales()'
-     */
-    public void testGetAvailableLocales() {
-        assertNotNull(Calendar.getAvailableLocales());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getAvailableULocales()'
-     */
-    public void testGetAvailableULocales() {
-        assertNotNull(Calendar.getAvailableULocales());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getTime()'
-     */
-    public void testGetTime() {
-        Calendar cal = Calendar.getInstance();
-        assertNotNull(cal.getTime());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.setTime(Date)'
-     */
-    public void testSetTime() {
-        Calendar cal = Calendar.getInstance();
-        cal.clear();
-        cal.set(2006, 0, 20, 9, 30, 0);
-        Date date = cal.getTime();
-        cal = Calendar.getInstance();
-        cal.setTime(date);
-        assertEquals(date, cal.getTime());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getTimeInMillis()'
-     */
-    public void testGetTimeInMillis() {
-        Calendar cal = Calendar.getInstance();
-        assertTrue(0 != cal.getTimeInMillis());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.setTimeInMillis(long)'
-     */
-    public void testSetTimeInMillis() {
-        Calendar cal = Calendar.getInstance();
-        cal.clear();
-        cal.set(2006, 0, 20, 9, 30, 0);
-        long millis = cal.getTimeInMillis();
-        Date date = cal.getTime();
-        
-        cal = Calendar.getInstance();
-        cal.setTimeInMillis(millis);
-        
-        assertEquals(date, cal.getTime());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.get(int)'
-     */
-    public void testGet() {
-        Calendar cal = Calendar.getInstance();
-        cal.clear();
-        cal.set(2006, 0, 20, 9, 30, 0);
-        assertEquals(0, cal.get(Calendar.MONTH));
-        assertEquals(20, cal.get(Calendar.DAY_OF_MONTH));
-        assertEquals(30, cal.get(Calendar.MINUTE));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.set(int, int)'
-     */
-    public void testSetIntInt() {
-        Calendar cal = Calendar.getInstance();
-        cal.set(Calendar.YEAR, 1977);
-        assertEquals(1977, cal.get(Calendar.YEAR));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.set(int, int, int)'
-     */
-    public void testSetIntIntInt() {
-        Calendar cal = Calendar.getInstance();
-        cal.set(1997, 9, 15);
-        assertEquals(15, cal.get(Calendar.DATE));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.set(int, int, int, int, int)'
-     */
-    public void testSetIntIntIntIntInt() {
-        Calendar cal = Calendar.getInstance();
-        cal.set(1997, 9, 15, 14, 25);
-        assertEquals(25, cal.get(Calendar.MINUTE));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.set(int, int, int, int, int, int)'
-     */
-    public void testSetIntIntIntIntIntInt() {
-        Calendar cal = Calendar.getInstance();
-        cal.set(1997, 9, 15, 14, 25, 51);
-        assertEquals(51, cal.get(Calendar.SECOND));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.clear()'
-     */
-    public void testClear() {
-        Calendar cal = Calendar.getInstance();
-        cal.set(1997, 9, 15, 14, 25, 51);
-        cal.clear();
-        assertEquals(0, cal.get(Calendar.MONTH));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.clear(int)'
-     */
-    public void testClearInt() {
-        Calendar cal = Calendar.getInstance();
-        cal.set(1997, 9, 15, 14, 25, 51);
-        assertTrue(cal.isSet(Calendar.DAY_OF_MONTH));
-        cal.clear(Calendar.DAY_OF_MONTH);
-        assertFalse(cal.isSet(Calendar.DAY_OF_MONTH));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.isSet(int)'
-     */
-    public void testIsSet() {
-        // see testClearInt
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.equals(Object)'
-     */
-    public void testEqualsObject() {
-        // tested by testHashCode
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.isEquivalentTo(Calendar)'
-     */
-    public void testIsEquivalentTo() {
-        Calendar cal = Calendar.getInstance();
-        Calendar cal2 = Calendar.getInstance();
-        cal2.set(1994, 6, 21, 8, 7);
-        assertTrue(cal.isEquivalentTo(cal2));
-        cal.setTimeZone(TimeZone.getTimeZone("CST"));
-        cal2.setTimeZone(TimeZone.getTimeZone("PDT"));
-        assertFalse(cal.isEquivalentTo(cal2));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.before(Object)'
-     */
-    public void testBefore() {
-        Calendar cal = Calendar.getInstance();
-        cal.set(Calendar.YEAR, 1990);
-        assertTrue(cal.before(new Date()));
-        assertTrue(cal.before(Calendar.getInstance()));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.after(Object)'
-     */
-    public void testAfter() {
-        Calendar cal = Calendar.getInstance();
-        cal.set(Calendar.YEAR, 3058);
-        assertTrue(cal.after(new Date()));
-        assertTrue(cal.after(Calendar.getInstance()));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getActualMaximum(int)'
-     */
-    public void testGetActualMaximum() {
-        Calendar cal = Calendar.getInstance(Locale.US);
-        assertEquals(11, cal.getActualMaximum(Calendar.MONTH));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getActualMinimum(int)'
-     */
-    public void testGetActualMinimum() {
-        Calendar cal = Calendar.getInstance(Locale.US);
-        assertEquals(0, cal.getActualMinimum(Calendar.MONTH));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.roll(int, boolean)'
-     */
-    public void testRollIntBoolean() {
-        Calendar cal = Calendar.getInstance(Locale.US);
-        cal.set(1997, 1, 27);
-        cal.roll(Calendar.DATE, true);
-        assertEquals(28, cal.get(Calendar.DATE));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.roll(int, int)'
-     */
-    public void testRollIntInt() {
-        Calendar cal = Calendar.getInstance(Locale.US);
-        cal.set(1997, 1, 27);
-        cal.roll(Calendar.DATE, 3);
-        assertEquals(2, cal.get(Calendar.DATE));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.add(int, int)'
-     */
-    public void testAdd() {
-        Calendar cal = Calendar.getInstance(Locale.US);
-        cal.set(1997, 1, 27);
-        cal.add(Calendar.DATE, 3);
-        assertEquals(2, cal.get(Calendar.DATE));
-        assertEquals(2, cal.get(Calendar.MONTH));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getDisplayName(Locale)'
-     */
-    public void testGetDisplayNameLocale() {
-        Calendar cal = Calendar.getInstance();
-        assertEquals("Gregorian Calendar", cal.getDisplayName(Locale.US));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getDisplayName(ULocale)'
-     */
-    public void testGetDisplayNameULocale() {
-        Calendar cal = Calendar.getInstance();
-        assertEquals("Gregorian Calendar", cal.getDisplayName(ULocale.US));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.compareTo(Calendar)'
-     */
-    public void testCompareToCalendar() {
-        Calendar cal = Calendar.getInstance();
-        cal.set(Calendar.YEAR, 1990);
-        assertTrue(0 > cal.compareTo(Calendar.getInstance()));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.compareTo(Object)'
-     */
-    public void testCompareToObject() {
-        Calendar cal = Calendar.getInstance();
-        cal.set(Calendar.YEAR, 1990);
-        assertTrue(0 > cal.compareTo(Calendar.getInstance()));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getDateTimeFormat(int, int, Locale)'
-     */
-    public void testGetDateTimeFormatIntIntLocale() {
-        Calendar cal = Calendar.getInstance();
-        cal.set(1990, 8, 16, 20, 3);
-        DateFormat df = cal.getDateTimeFormat(DateFormat.LONG, DateFormat.SHORT, Locale.US);
-        assertEquals("September 16, 1990 8:03 PM", df.format(cal));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getDateTimeFormat(int, int, ULocale)'
-     */
-    public void testGetDateTimeFormatIntIntULocale() {
-        Calendar cal = Calendar.getInstance();
-        cal.set(1990, 8, 16, 20, 3);
-        DateFormat df = cal.getDateTimeFormat(DateFormat.LONG, DateFormat.SHORT, ULocale.US);
-        assertEquals("September 16, 1990 8:03 PM", df.format(cal));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.fieldDifference(Date, int)'
-     */
-    public void testFieldDifference() {
-        Calendar cal = Calendar.getInstance();
-        cal.set(Calendar.DAY_OF_MONTH, 0);
-        Date date = cal.getTime();
-        cal.add(Calendar.DAY_OF_MONTH, 5);
-        assertEquals(-5, cal.fieldDifference(date, Calendar.DAY_OF_MONTH));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getTimeZone()'
-     */
-    public void testGetTimeZone() {
-        Calendar cal = Calendar.getInstance();
-        assertNotNull(cal.getTimeZone());
-    }
-    
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.setTimeZone(TimeZone)'
-     */
-    public void testSetTimeZone() {
-        Calendar cal = Calendar.getInstance();
-        TimeZone value1 = cal.getTimeZone();
-        String tzn = "PDT".equals(value1.getID()) ? "CST" : "PDT";
-        TimeZone value2 = TimeZone.getTimeZone(tzn);
-        cal.setTimeZone(value2);
-        TimeZone result = cal.getTimeZone();
-        assertNotEqual(value1, result);
-        assertEquals(value2, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.setLenient(boolean)'
-     */
-    public void testSetLenient() {
-        Calendar cal = Calendar.getInstance();
-        boolean lenient = cal.isLenient();
-        cal.setLenient(!lenient);
-        assertFalse(lenient == cal.isLenient());
-        
-        // not testing if it has the expected effect
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.isLenient()'
-     */
-    public void testIsLenient() {
-        // tested by testSetLenient
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.setFirstDayOfWeek(int)'
-     */
-    public void testSetFirstDayOfWeek() {
-        Calendar cal = Calendar.getInstance();
-        int firstDay = cal.getFirstDayOfWeek();
-        cal.setFirstDayOfWeek(firstDay+1);
-        assertEquals(firstDay+1, cal.getFirstDayOfWeek());
-
-        // don't test functionality
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getFirstDayOfWeek()'
-     */
-    public void testGetFirstDayOfWeek() {
-        // tested by testSetFirstDayOfWeek
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.setMinimalDaysInFirstWeek(int)'
-     */
-    public void testSetMinimalDaysInFirstWeek() {
-        Calendar cal = Calendar.getInstance();
-        int firstDay = cal.getMinimalDaysInFirstWeek();
-        cal.setMinimalDaysInFirstWeek(firstDay+1);
-        assertEquals(firstDay+1, cal.getMinimalDaysInFirstWeek());
-
-        // don't test functionality
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getMinimalDaysInFirstWeek()'
-     */
-    public void testGetMinimalDaysInFirstWeek() {
-        // tested by testSetMinimalDaysInFirstWeek
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getMinimum(int)'
-     */
-    public void testGetMinimum() {
-        Calendar cal = Calendar.getInstance();
-        assertEquals(1, cal.getMinimum(Calendar.DAY_OF_WEEK));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getMaximum(int)'
-     */
-    public void testGetMaximum() {
-        Calendar cal = Calendar.getInstance();
-        assertEquals(7, cal.getMaximum(Calendar.DAY_OF_WEEK));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getGreatestMinimum(int)'
-     */
-    public void testGetGreatestMinimum() {
-        Calendar cal = Calendar.getInstance();
-        assertEquals(1, cal.getGreatestMinimum(Calendar.DATE));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getLeastMaximum(int)'
-     */
-    public void testGetLeastMaximum() {
-        Calendar cal = Calendar.getInstance();
-        assertEquals(28, cal.getLeastMaximum(Calendar.DATE));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getDayOfWeekType(int)'
-     */
-    public void testGetDayOfWeekType() {
-        Calendar cal = Calendar.getInstance(Locale.US);
-        assertEquals(Calendar.WEEKDAY, cal.getDayOfWeekType(Calendar.FRIDAY));
-        assertEquals(Calendar.WEEKEND, cal.getDayOfWeekType(Calendar.SATURDAY));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.isWeekend(Date)'
-     */
-    public void testIsWeekendDate() {
-        Calendar cal = Calendar.getInstance(Locale.US);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
-        assertTrue(cal.isWeekend(cal.getTime()));
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
-        assertFalse(cal.isWeekend(cal.getTime()));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.isWeekend()'
-     */
-    public void testIsWeekend() {
-        Calendar cal = Calendar.getInstance(Locale.US);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
-        assertTrue(cal.isWeekend());
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
-        assertFalse(cal.isWeekend());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.clone()'
-     */
-    public void testClone() {
-        // tested by testHashCode
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.toString()'
-     */
-    public void testToString() {
-        Calendar cal = Calendar.getInstance();
-        assertNotNull(cal.toString());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.Calendar.getType()'
-     */
-    public void testGetType() {
-        Calendar cal = Calendar.getInstance(Locale.US);
-        assertEquals("gregorian", cal.getType());
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollationKeyTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollationKeyTest.java
deleted file mode 100644
index 1fe5002..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollationKeyTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2006-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.tests;
-
-import com.ibm.icu.text.CollationKey;
-import com.ibm.icu.text.Collator;
-
-public class CollationKeyTest extends ICUTestCase {
-
-    /*
-     * Test method for 'com.ibm.icu.text.CollationKey.hashCode()'
-     */
-    public void testHashCode() {
-        Collator c = Collator.getInstance();
-        c.setStrength(Collator.PRIMARY);
-        CollationKey k1 = c.getCollationKey("This");
-        CollationKey k2 = c.getCollationKey("this");
-        c.setStrength(Collator.TERTIARY);
-        CollationKey kn = c.getCollationKey("this");
-        testEHCS(k1, k2, kn);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.CollationKey.CollationKey(CollationKey)'
-     */
-    public void testCollationKey() {
-        // implicitly tested everywhere
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.CollationKey.compareTo(CollationKey)'
-     */
-    public void testCompareToCollationKey() {
-        Collator c = Collator.getInstance();
-        c.setStrength(Collator.PRIMARY);
-        CollationKey k1 = c.getCollationKey("This");
-        CollationKey k2 = c.getCollationKey("this");
-        c.setStrength(Collator.TERTIARY);
-        CollationKey k3 = c.getCollationKey("this");
-        assertTrue(0 == k1.compareTo(k2));
-        assertFalse(0 == k1.compareTo(k3));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.CollationKey.compareTo(Object)'
-     */
-    public void testCompareToObject() {
-        Collator c = Collator.getInstance();
-        c.setStrength(Collator.PRIMARY);
-        CollationKey k1 = c.getCollationKey("This");
-        CollationKey k2 = c.getCollationKey("this");
-        assertTrue(0 == k1.compareTo(k2));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.CollationKey.equals(Object)'
-     */
-    public void testEqualsObject() {
-        Collator c = Collator.getInstance();
-        c.setStrength(Collator.PRIMARY);
-        CollationKey k1 = c.getCollationKey("This");
-        CollationKey k2 = c.getCollationKey("this");
-        assertTrue(k1.equals((Object)k2));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.CollationKey.toString()'
-     */
-    public void testToString() {
-        Collator c = Collator.getInstance();
-        c.setStrength(Collator.PRIMARY);
-        CollationKey k1 = c.getCollationKey("This");
-        assertNotNull(k1.toString());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.CollationKey.getSourceString()'
-     */
-    public void testGetSourceString() {
-        Collator c = Collator.getInstance();
-        c.setStrength(Collator.PRIMARY);
-        CollationKey k1 = c.getCollationKey("This");
-        assertEquals("This", k1.getSourceString());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.CollationKey.toByteArray()'
-     */
-    public void testToByteArray() {
-        Collator c = Collator.getInstance();
-        c.setStrength(Collator.PRIMARY);
-        CollationKey k1 = c.getCollationKey("This");
-        byte[] key = k1.toByteArray();
-        assertNotNull(key);
-        assertTrue(0 < key.length);
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollatorTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollatorTest.java
deleted file mode 100644
index 8cb743d..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/CollatorTest.java
+++ /dev/null
@@ -1,207 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2006-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.tests;
-
-import java.util.Locale;
-
-import com.ibm.icu.text.CollationKey;
-import com.ibm.icu.text.Collator;
-import com.ibm.icu.util.ULocale;
-
-public class CollatorTest extends ICUTestCase {
-    private static final String s1 = "Fu\u0308nf"; // capital F + u + diaresis
-    private static final String s2 = "fu\u0308nf"; // u + diaresis
-    private static final String s3 = "f\u00fcnf"; // u-umlaut
-    private static final String s4 = "fu\u0308\u0316nf"; // u + diaresis above + grave below
-    private static final String s5 = "fu\u0316\u0308nf"; // u + grave below + diaresis above
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.hashCode()'
-     */
-    public void testHashCode() {
-        Collator c = Collator.getInstance();
-        c.setStrength(Collator.SECONDARY);
-        Collator c2 = Collator.getInstance();
-        c2.setStrength(Collator.SECONDARY);
-        Collator cn = Collator.getInstance();
-        cn.setStrength(Collator.TERTIARY);
-        testEHCS(c, c2, cn);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.Collator(Collator)'
-     */
-    public void testCollator() {
-        // implicitly tested everywhere
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.setStrength(int)'
-     */
-    public void testSetStrength() {
-        Collator c = Collator.getInstance();
-        c.setStrength(Collator.PRIMARY);
-        assertTrue(0 == c.compare(s1, s2));
-        c.setStrength(Collator.SECONDARY);
-        assertTrue(0 == c.compare(s1, s2));
-        c.setStrength(Collator.TERTIARY);
-        assertTrue(0 < c.compare(s1, s2));
-        assertTrue(0 == c.compare(s2, s3));
-        c.setStrength(Collator.QUATERNARY);
-        assertTrue(0 > c.compare(s2, s3));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.setDecomposition(int)'
-     */
-    public void testSetDecomposition() {
-        Collator c = Collator.getInstance();
-        c.setStrength(Collator.TERTIARY);
-        assertTrue(0 != c.compare(s4, s5));
-        c.setDecomposition(Collator.IDENTICAL);
-        assertTrue(0 == c.compare(s4, s5));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.getInstance()'
-     */
-    public void testGetInstance() {
-        // implicitly tested everywhere
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.getInstance(ULocale)'
-     */
-    public void testGetInstanceULocale() {
-        Collator c = Collator.getInstance(ULocale.GERMANY);
-        assertNotNull(c);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.getInstance(Locale)'
-     */
-    public void testGetInstanceLocale() {
-        Collator c = Collator.getInstance(Locale.GERMANY);
-        assertNotNull(c);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.getAvailableLocales()'
-     */
-    public void testGetAvailableLocales() {
-        assertNotNull(Collator.getAvailableLocales());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.getAvailableULocales()'
-     */
-    public void testGetAvailableULocales() {
-        assertNotNull(Collator.getAvailableULocales());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.getKeywords()'
-     */
-    public void testGetKeywords() {
-        assertEquals(0, Collator.getKeywords().length);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.getKeywordValues(String)'
-     */
-    public void testGetKeywordValues() {
-        assertEquals(0, Collator.getKeywordValues("").length);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.getStrength()'
-     */
-    public void testGetStrength() {
-        Collator c = Collator.getInstance();
-        c.setStrength(Collator.PRIMARY);
-        assertEquals(Collator.PRIMARY, c.getStrength());
-        c.setStrength(Collator.SECONDARY);
-        assertEquals(Collator.SECONDARY, c.getStrength());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.getDecomposition()'
-     */
-    public void testGetDecomposition() {
-        Collator c = Collator.getInstance();
-        c.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
-        assertEquals(Collator.CANONICAL_DECOMPOSITION, c.getDecomposition());
-        c.setDecomposition(Collator.NO_DECOMPOSITION);
-        assertEquals(Collator.NO_DECOMPOSITION, c.getDecomposition());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.compare(Object, Object)'
-     */
-    public void testCompareObjectObject() {
-        Collator c = Collator.getInstance();
-        c.setStrength(Collator.PRIMARY);
-        assertTrue(0 == c.compare((Object)s1, (Object)s2));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.equals(String, String)'
-     */
-    public void testEqualsStringString() {
-        Collator c = Collator.getInstance();
-        c.setStrength(Collator.PRIMARY);
-        assertTrue(c.equals(s1, s2));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.compare(String, String)'
-     */
-    public void testCompareStringString() {
-        Collator c = Collator.getInstance();
-        c.setStrength(Collator.PRIMARY);
-        assertTrue(0 == c.compare(s1, s2));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.getCollationKey(String)'
-     */
-    public void testGetCollationKey() {
-        Collator c = Collator.getInstance();
-        c.setStrength(Collator.PRIMARY);
-        CollationKey k1 = c.getCollationKey(s1);
-        CollationKey k2 = c.getCollationKey(s2);
-        assertTrue(k1.equals(k2));
-        c.setStrength(Collator.TERTIARY);
-        k1 = c.getCollationKey(s1);
-        k2 = c.getCollationKey(s2);
-        assertFalse(k1.equals(k2));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.toString()'
-     */
-    public void testToString() {
-        assertNotNull(Collator.getInstance().toString());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.clone()'
-     */
-    public void testClone() {
-        // tested above
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.Collator.equals(Object)'
-     */
-    public void testEqualsObject() {
-        // tested above
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatSymbolsTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatSymbolsTest.java
deleted file mode 100644
index a98dafb..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatSymbolsTest.java
+++ /dev/null
@@ -1,259 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2006-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.tests;
-
-import java.util.Locale;
-
-import com.ibm.icu.text.DateFormatSymbols;
-import com.ibm.icu.util.ULocale;
-
-public class DateFormatSymbolsTest extends ICUTestCase {
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.hashCode()'
-     */
-    public void testHashCode() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        DateFormatSymbols dfs2 = new DateFormatSymbols(ULocale.US);
-        DateFormatSymbols dfsn = new DateFormatSymbols(Locale.US);
-        dfsn.setAmPmStrings(new String[] { "sw", "xw" });
-        testEHCS(dfs, dfs2, dfsn);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.DateFormatSymbols(DateFormatSymbols)'
-     */
-    public void testDateFormatSymbolsDateFormatSymbols() {
-        // implicitly tested everywhere
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.DateFormatSymbols()'
-     */
-    public void testDateFormatSymbols() {
-        DateFormatSymbols dfs = new DateFormatSymbols();
-        assertNotNull(dfs.getWeekdays());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.DateFormatSymbols(Locale)'
-     */
-    public void testDateFormatSymbolsLocale() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        assertNotNull(dfs.getWeekdays());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.DateFormatSymbols(ULocale)'
-     */
-    public void testDateFormatSymbolsULocale() {
-        DateFormatSymbols dfs = new DateFormatSymbols(ULocale.US);
-        assertNotNull(dfs.getWeekdays());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.getEras()'
-     */
-    public void testGetEras() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        assertNotNull(dfs.getEras());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.setEras(String[])'
-     */
-    public void testSetEras() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        String[] oldvalue = dfs.getEras();
-        String[] newvalue = (String[])oldvalue.clone();
-        newvalue[0] = newvalue[0] + "!";
-        dfs.setEras(newvalue);
-        String[] result = dfs.getEras();
-        assertArraysNotEqual(oldvalue, result);
-        assertArraysEqual(newvalue, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.getMonths()'
-     */
-    public void testGetMonths() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        assertNotNull(dfs.getMonths());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.setMonths(String[])'
-     */
-    public void testSetMonths() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        String[] oldvalue = dfs.getMonths();
-        String[] newvalue = (String[])oldvalue.clone();
-        newvalue[0] = newvalue[0] + "!";
-        dfs.setMonths(newvalue);
-        String[] result = dfs.getMonths();
-        assertArraysNotEqual(oldvalue, result);
-        assertArraysEqual(newvalue, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.getShortMonths()'
-     */
-    public void testGetShortMonths() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        assertNotNull(dfs.getShortMonths());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.setShortMonths(String[])'
-     */
-    public void testSetShortMonths() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        String[] oldvalue = dfs.getShortMonths();
-        String[] newvalue = (String[])oldvalue.clone();
-        newvalue[0] = newvalue[0] + "!";
-        dfs.setShortMonths(newvalue);
-        String[] result = dfs.getShortMonths();
-        assertArraysNotEqual(oldvalue, result);
-        assertArraysEqual(newvalue, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.getWeekdays()'
-     */
-    public void testGetWeekdays() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        assertNotNull(dfs.getShortMonths());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.setWeekdays(String[])'
-     */
-    public void testSetWeekdays() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        String[] oldvalue = dfs.getWeekdays();
-        String[] newvalue = (String[])oldvalue.clone();
-        newvalue[0] = newvalue[0] + "!";
-        dfs.setWeekdays(newvalue);
-        String[] result = dfs.getWeekdays();
-        assertArraysNotEqual(oldvalue, result);
-        assertArraysEqual(newvalue, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.getShortWeekdays()'
-     */
-    public void testGetShortWeekdays() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        assertNotNull(dfs.getShortWeekdays());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.setShortWeekdays(String[])'
-     */
-    public void testSetShortWeekdays() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        String[] oldvalue = dfs.getShortWeekdays();
-        String[] newvalue = (String[])oldvalue.clone();
-        newvalue[0] = newvalue[0] + "!";
-        dfs.setShortWeekdays(newvalue);
-        String[] result = dfs.getShortWeekdays();
-        assertArraysNotEqual(oldvalue, result);
-        assertArraysEqual(newvalue, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.getAmPmStrings()'
-     */
-    public void testGetAmPmStrings() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        assertNotNull(dfs.getAmPmStrings());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.setAmPmStrings(String[])'
-     */
-    public void testSetAmPmStrings() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        String[] oldvalue = dfs.getAmPmStrings();
-        String[] newvalue = (String[])oldvalue.clone();
-        newvalue[0] = newvalue[0] + "!";
-        dfs.setAmPmStrings(newvalue);
-        String[] result = dfs.getAmPmStrings();
-        assertArraysNotEqual(oldvalue, result);
-        assertArraysEqual(newvalue, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.getZoneStrings()'
-     */
-    public void testGetZoneStrings() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        assertNotNull(dfs.getZoneStrings());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.setZoneStrings(String[][])'
-     */
-    public void testSetZoneStrings() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        String[][] oldvalue = dfs.getZoneStrings();
-        String[][] newvalue = (String[][])cloneComplex(oldvalue);
-        newvalue[0][0] = newvalue[0][0] + "!";
-        dfs.setZoneStrings(newvalue);
-        String[][] result = dfs.getZoneStrings();
-        assertArraysNotEqual(oldvalue, result);
-        assertArraysEqual(newvalue, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.getLocalPatternChars()'
-     */
-    public void testGetLocalPatternChars() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        assertNotNull(dfs.getLocalPatternChars());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.setLocalPatternChars(String)'
-     */
-    public void testSetLocalPatternChars() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        String pat = dfs.getLocalPatternChars();
-        StringBuffer buf = new StringBuffer(pat);
-        buf.setCharAt(0, (char)(pat.charAt(0) + 1));
-        String pat2 = buf.toString();
-        dfs.setLocalPatternChars(pat2);
-        String pat3 = dfs.getLocalPatternChars();
-        assertNotEqual(pat, pat2);
-        assertEquals(pat2, pat3);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.toString()'
-     */
-    public void testToString() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        assertNotNull(dfs.toString());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.clone()'
-     */
-    public void testClone() {
-        // tested by testHashCode
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormatSymbols.equals(Object)'
-     */
-    public void testEqualsObject() {
-        // tested by testHashCode
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatTest.java
deleted file mode 100644
index 0f2fc7d..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DateFormatTest.java
+++ /dev/null
@@ -1,456 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2006-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.tests;
-
-import java.text.FieldPosition;
-import java.text.ParseException;
-import java.text.ParsePosition;
-import java.util.Date;
-import java.util.Locale;
-
-import com.ibm.icu.text.DateFormat;
-import com.ibm.icu.text.NumberFormat;
-import com.ibm.icu.util.Calendar;
-import com.ibm.icu.util.TimeZone;
-import com.ibm.icu.util.ULocale;
-
-public class DateFormatTest extends ICUTestCase {
-    private Calendar aCal;
-    private Calendar anESTCal;
-    private Date aDate;
-    private String aDateString;
-    private String aTimeString;
-    private String anESTTimeString;
-    private String aDateTimeString;
-    private String aShortDateTimeString;
-    private String aDefaultESTDateTimeString;
-    private DateFormat aDF;
-    private StringBuffer aBuf;
-    private FieldPosition anFP;
-    private FieldPosition anFPField;
-
-    private static int YEAR_POS_START = 8;
-    private static int YEAR_POS_END = 12;
-
-    protected void setUp() throws Exception {
-        super.setUp();
-                
-        java.util.GregorianCalendar gcal = new java.util.GregorianCalendar();
-        gcal.clear();
-        gcal.set(java.util.GregorianCalendar.YEAR, 1990);
-        gcal.set(java.util.GregorianCalendar.MONTH, java.util.GregorianCalendar.DECEMBER);
-        gcal.set(java.util.GregorianCalendar.DATE, 17);
-        gcal.set(java.util.GregorianCalendar.HOUR, 5);
-        gcal.set(java.util.GregorianCalendar.MINUTE, 17);
-        aCal = new Calendar(gcal);
-        anESTCal = Calendar.getInstance();
-        anESTCal.setTimeZone(TimeZone.getTimeZone("EST"));
-        aDate = gcal.getTime();
-        aDateString = "Dec 17, 1990"; // medium -- the default
-        aTimeString = "5:17:00 AM"; // medium
-        anESTTimeString = "8:17:00 AM";
-        aDateTimeString = "Dec 17, 1990 5:17:00 AM"; // medium, medium
-        aDefaultESTDateTimeString = "Dec 17, 1990 8:17 AM"; // medium, short -- the default
-        aShortDateTimeString = "12/17/90 5:17 AM"; // short, short
-        aDF = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US);
-        aBuf = new StringBuffer();
-        anFP = new FieldPosition(DateFormat.YEAR_FIELD);
-        anFPField = new FieldPosition(DateFormat.Field.YEAR);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.hashCode()'
-     */
-    public final void testHashCode() {
-        DateFormat df = DateFormat.getInstance();
-        DateFormat eq = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
-        testEHCS(df, eq, aDF);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.DateFormat(DateFormat)'
-     */
-    public final void testDateFormat() {
-        DateFormat df = new DateFormat(java.text.DateFormat.getInstance());
-        assertEquals(DateFormat.getInstance(), df);
-    }
-
-    private void assertEqualDateString(StringBuffer buf) {
-        assertEquals(aDateTimeString, buf.toString());
-    }
-        
-    private void assertEqualDateString(String str) {
-        assertEquals(aDateTimeString, str);
-    }
-        
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.format(Object, StringBuffer, FieldPosition)'
-     */
-    public final void testFormatObjectStringBufferFieldPosition() {
-        assertEqualDateString(aDF.format(aDate, aBuf, anFP));
-        assertEquals(YEAR_POS_START, anFP.getBeginIndex());
-        assertEquals(YEAR_POS_END, anFP.getEndIndex());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.format(Calendar, StringBuffer, FieldPosition)'
-     */
-    public final void testFormatCalendarStringBufferFieldPosition() {
-        assertEqualDateString(aDF.format(aCal, aBuf, anFP));
-        assertEquals(YEAR_POS_START, anFP.getBeginIndex());
-        assertEquals(YEAR_POS_END, anFP.getEndIndex());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.format(Date, StringBuffer, FieldPosition)'
-     */
-    public final void testFormatDateStringBufferFieldPosition() {
-        assertEqualDateString(aDF.format(aDate, aBuf, anFPField));
-        assertEquals(YEAR_POS_START, anFPField.getBeginIndex());
-        assertEquals(YEAR_POS_END, anFPField.getEndIndex());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.format(Date)'
-     */
-    public final void testFormatDate() {
-        assertEqualDateString(aDF.format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.parse(String)'
-     */
-    public final void testParseString() throws Exception {
-        assertEquals(aDate, aDF.parse(aDateTimeString));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.parse(String, Calendar, ParsePosition)'
-     */
-    public final void testParseStringCalendarParsePosition() {
-        aDF.parse(aDateTimeString, aCal, new ParsePosition(0));
-        assertEquals(aDate, aCal.getTime());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.parse(String, ParsePosition)'
-     */
-    public final void testParseStringParsePosition() {
-        assertEquals(aDate, aDF.parse(aDateTimeString, new ParsePosition(0)));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.parseObject(String, ParsePosition)'
-     */
-    public final void testParseObjectStringParsePosition() {
-        assertEquals(aDate, aDF.parseObject(aDateTimeString, new ParsePosition(0)));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance()'
-     */
-    public final void testGetTimeInstance() {
-        assertEquals(aTimeString, DateFormat.getTimeInstance().format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(int)'
-     */
-    public final void testGetTimeInstanceInt() {
-        assertEquals(aTimeString, DateFormat.getTimeInstance(DateFormat.MEDIUM).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(int, Locale)'
-     */
-    public final void testGetTimeInstanceIntLocale() {
-        assertEquals(aTimeString, DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.US).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(int, ULocale)'
-     */
-    public final void testGetTimeInstanceIntULocale() {
-        assertEquals(aTimeString, DateFormat.getTimeInstance(DateFormat.MEDIUM, ULocale.US).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance()'
-     */
-    public final void testGetDateInstance() {
-        assertEquals(aDateString, DateFormat.getDateInstance().format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(int)'
-     */
-    public final void testGetDateInstanceInt() {
-        assertEquals(aDateString, DateFormat.getDateInstance(DateFormat.MEDIUM).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(int, Locale)'
-     */
-    public final void testGetDateInstanceIntLocale() {
-        assertEquals(aDateString, DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.US).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(int, ULocale)'
-     */
-    public final void testGetDateInstanceIntULocale() {
-        assertEquals(aDateString, DateFormat.getDateInstance(DateFormat.MEDIUM, ULocale.US).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance()'
-     */
-    public final void testGetDateTimeInstance() {
-        assertEquals(aDateTimeString, DateFormat.getDateTimeInstance().format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(int, int)'
-     */
-    public final void testGetDateTimeInstanceIntInt() {
-        assertEquals(aDateTimeString, 
-                     DateFormat.getDateTimeInstance(
-                                                    DateFormat.MEDIUM, DateFormat.MEDIUM).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(int, int, Locale)'
-     */
-    public final void testGetDateTimeInstanceIntIntLocale() {
-        assertEquals(aDateTimeString, 
-                     DateFormat.getDateTimeInstance(
-                                                    DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(int, int, ULocale)'
-     */
-    public final void testGetDateTimeInstanceIntIntULocale() {
-        assertEquals(aDateTimeString, 
-                     DateFormat.getDateTimeInstance(
-                                                    DateFormat.MEDIUM, DateFormat.MEDIUM, ULocale.US).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getInstance()'
-     */
-    public final void testGetInstance() {
-        assertEquals(aShortDateTimeString, DateFormat.getInstance().format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getAvailableLocales()'
-     */
-    public final void testGetAvailableLocales() {
-        Locale[] locales = DateFormat.getAvailableLocales();
-        if (ICUTestCase.testingWrapper) {
-            ICUTestCase.assertArraysEqual(java.text.DateFormat.getAvailableLocales(), locales);
-        } else {
-            assertNotNull(locales);
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.setCalendar(Calendar)'
-     */
-    public final void testSetCalendar() {
-        Calendar cal = Calendar.getInstance();
-        cal.setTimeZone(TimeZone.getTimeZone("EST"));
-        DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
-        df.setCalendar(cal);
-        assertEquals("8:17 AM", df.format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getCalendar()'
-     */
-    public final void testGetCalendar() {
-        Calendar cal = Calendar.getInstance();
-        cal.setTimeZone(TimeZone.getTimeZone("EST"));
-        DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
-        df.setCalendar(cal);
-        assertEquals(cal, df.getCalendar());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.setNumberFormat(NumberFormat)'
-     */
-    public final void testSetNumberFormat() {
-        // no easy way to test effect of setting the number format
-        NumberFormat nf = NumberFormat.getInstance();
-        DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
-        df.setNumberFormat(nf);
-        // note, can't actually USE the dateformat since it changes the calendar
-        assertEquals(nf, df.getNumberFormat());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getNumberFormat()'
-     */
-    public final void testGetNumberFormat() {
-        // see testSetNumberFormat
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.setTimeZone(TimeZone)'
-     */
-    public final void testSetTimeZone() {
-        DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
-        TimeZone tz = TimeZone.getTimeZone("EST");
-        df.setTimeZone(tz);
-        assertEquals("8:17 AM", df.format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getTimeZone()'
-     */
-    public final void testGetTimeZone() {
-        DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
-        TimeZone tz = TimeZone.getTimeZone("EST");
-        df.setTimeZone(tz);
-        assertEquals(tz, df.getTimeZone());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.setLenient(boolean)'
-     */
-    public final void testSetLenient() throws Exception {
-        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
-        df.parse("2/31/90"); // succeeds, default is lenient
-        df.setLenient(false);
-        try {
-            df.parse("2/31/90");
-            throw new Exception("strict parse should have failed");
-        }
-        catch (ParseException e) {
-            // ok, this is what we expect
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.isLenient()'
-     */
-    public final void testIsLenient() {
-        DateFormat df = DateFormat.getInstance();
-        assertTrue(df.isLenient());
-        df.setLenient(false);
-        assertFalse(df.isLenient());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(Calendar, int, Locale)'
-     */
-    public final void testGetDateInstanceCalendarIntLocale() {
-        assertEquals(aDateString, DateFormat.getDateInstance(aCal, DateFormat.MEDIUM, Locale.US).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(Calendar, int, ULocale)'
-     */
-    public final void testGetDateInstanceCalendarIntULocale() {
-        assertEquals(aDateString, DateFormat.getDateInstance(aCal, DateFormat.MEDIUM, ULocale.US).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(Calendar, int, Locale)'
-     */
-    public final void testGetTimeInstanceCalendarIntLocale() {
-        assertEquals(anESTTimeString, DateFormat.getTimeInstance(anESTCal, DateFormat.MEDIUM, Locale.US).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(Calendar, int, ULocale)'
-     */
-    public final void testGetTimeInstanceCalendarIntULocale() {
-        assertEquals(anESTTimeString, DateFormat.getTimeInstance(anESTCal, DateFormat.MEDIUM, ULocale.US).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(Calendar, int, int, Locale)'
-     */
-    public final void testGetDateTimeInstanceCalendarIntIntLocale() {
-        assertEquals(aDefaultESTDateTimeString, DateFormat.getDateTimeInstance(anESTCal, DateFormat.MEDIUM, DateFormat.SHORT, Locale.US).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(Calendar, int, int, ULocale)'
-     */
-    public final void testGetDateTimeInstanceCalendarIntIntULocale() {
-        assertEquals(aDefaultESTDateTimeString, DateFormat.getDateTimeInstance(anESTCal, DateFormat.MEDIUM, DateFormat.SHORT, ULocale.US).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getInstance(Calendar, Locale)'
-     */
-    public final void testGetInstanceCalendarLocale() {
-        assertEquals(aDefaultESTDateTimeString, DateFormat.getInstance(anESTCal, Locale.US).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getInstance(Calendar, ULocale)'
-     */
-    public final void testGetInstanceCalendarULocale() {
-        assertEquals(aDefaultESTDateTimeString, DateFormat.getInstance(anESTCal, ULocale.US).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getInstance(Calendar)'
-     */
-    public final void testGetInstanceCalendar() {
-        assertEquals(aDefaultESTDateTimeString, DateFormat.getInstance(anESTCal).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getDateInstance(Calendar, int)'
-     */
-    public final void testGetDateInstanceCalendarInt() {
-        assertEquals(aDateString, DateFormat.getDateInstance(aCal, DateFormat.MEDIUM).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getTimeInstance(Calendar, int)'
-     */
-    public final void testGetTimeInstanceCalendarInt() {
-        assertEquals(anESTTimeString, DateFormat.getTimeInstance(anESTCal, DateFormat.MEDIUM).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.getDateTimeInstance(Calendar, int, int)'
-     */
-    public final void testGetDateTimeInstanceCalendarIntInt() {
-        assertEquals(aDefaultESTDateTimeString, DateFormat.getDateTimeInstance(anESTCal, DateFormat.MEDIUM, DateFormat.SHORT).format(aDate));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.toString()'
-     */
-    public final void testToString() {
-        assertNotNull(aDF.toString());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.clone()'
-     */
-    public final void testClone() {
-        // see testHashCode
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DateFormat.equals(Object)'
-     */
-    public final void testEqualsObject() {
-        // see testHashCode
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatSymbolsTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatSymbolsTest.java
deleted file mode 100644
index 155d838..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatSymbolsTest.java
+++ /dev/null
@@ -1,346 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2006-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.tests;
-
-import java.util.Locale;
-
-import com.ibm.icu.text.DecimalFormatSymbols;
-import com.ibm.icu.util.ULocale;
-
-public class DecimalFormatSymbolsTest extends ICUTestCase {
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.hashCode()'
-     */
-    public void testHashCode() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
-        DecimalFormatSymbols dfs2 = new DecimalFormatSymbols(ULocale.US);
-        DecimalFormatSymbols dfsn = new DecimalFormatSymbols(Locale.FRANCE);
-        testEHCS(dfs, dfs2, dfsn);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.DecimalFormatSymbols(DecimalFormatSymbols)'
-     */
-    public void testDecimalFormatSymbolsDecimalFormatSymbols() {
-        // implicitly tested everywhere
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.DecimalFormatSymbols()'
-     */
-    public void testDecimalFormatSymbols() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols();
-        assertTrue(-1 != dfs.getDecimalSeparator());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.DecimalFormatSymbols(Locale)'
-     */
-    public void testDecimalFormatSymbolsLocale() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
-        assertTrue(-1 != dfs.getDecimalSeparator());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.DecimalFormatSymbols(ULocale)'
-     */
-    public void testDecimalFormatSymbolsULocale() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        assertTrue(-1 != dfs.getDecimalSeparator());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getZeroDigit()'
-     */
-    public void testGetZeroDigit() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        assertEquals('0', dfs.getZeroDigit());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setZeroDigit(char)'
-     */
-    public void testSetZeroDigit() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        char value = dfs.getZeroDigit();
-        char value1 = (char)(value + 1);
-        dfs.setZeroDigit(value1);
-        char result = dfs.getZeroDigit();
-        assertNotEqual(value, result);
-        assertEquals(value1, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getGroupingSeparator()'
-     */
-    public void testGetGroupingSeparator() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        assertEquals(',', dfs.getGroupingSeparator());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setGroupingSeparator(char)'
-     */
-    public void testSetGroupingSeparator() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        char value = dfs.getGroupingSeparator();
-        char value1 = (char)(value + 1);
-        dfs.setGroupingSeparator(value1);
-        char result = dfs.getGroupingSeparator();
-        assertNotEqual(value, result);
-        assertEquals(value1, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getDecimalSeparator()'
-     */
-    public void testGetDecimalSeparator() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        assertEquals('.', dfs.getDecimalSeparator());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setDecimalSeparator(char)'
-     */
-    public void testSetDecimalSeparator() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        char value = dfs.getDecimalSeparator();
-        char value1 = (char)(value + 1);
-        dfs.setDecimalSeparator(value1);
-        char result = dfs.getDecimalSeparator();
-        assertNotEqual(value, result);
-        assertEquals(value1, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getPerMill()'
-     */
-    public void testGetPerMill() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        assertEquals('\u2030', dfs.getPerMill());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setPerMill(char)'
-     */
-    public void testSetPerMill() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        char value = dfs.getPerMill();
-        char value1 = (char)(value + 1);
-        dfs.setPerMill(value1);
-        char result = dfs.getPerMill();
-        assertNotEqual(value, result);
-        assertEquals(value1, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getPercent()'
-     */
-    public void testGetPercent() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        assertEquals('%', dfs.getPercent());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setPercent(char)'
-     */
-    public void testSetPercent() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        char value = dfs.getPercent();
-        char value1 = (char)(value + 1);
-        dfs.setPercent(value1);
-        char result = dfs.getPercent();
-        assertNotEqual(value, result);
-        assertEquals(value1, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getDigit()'
-     */
-    public void testGetDigit() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        assertEquals('#', dfs.getDigit());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setDigit(char)'
-     */
-    public void testSetDigit() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        char value = dfs.getDigit();
-        char value1 = (char)(value + 1);
-        dfs.setDigit(value1);
-        char result = dfs.getDigit();
-        assertNotEqual(value, result);
-        assertEquals(value1, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getPatternSeparator()'
-     */
-    public void testGetPatternSeparator() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        assertEquals(';', dfs.getPatternSeparator());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setPatternSeparator(char)'
-     */
-    public void testSetPatternSeparator() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        char value = dfs.getPatternSeparator();
-        char value1 = (char)(value + 1);
-        dfs.setPatternSeparator(value1);
-        char result = dfs.getPatternSeparator();
-        assertNotEqual(value, result);
-        assertEquals(value1, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getInfinity()'
-     */
-    public void testGetInfinity() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        assertEquals("\u221e", dfs.getInfinity());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setInfinity(String)'
-     */
-    public void testSetInfinity() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        String value = dfs.getInfinity();
-        String value1 = value + "!";
-        dfs.setInfinity(value1);
-        String result = dfs.getInfinity();
-        assertNotEqual(value, result);
-        assertEquals(value1, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getNaN()'
-     */
-    public void testGetNaN() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        assertNotNull(dfs.getNaN()); // java returns missing character???
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setNaN(String)'
-     */
-    public void testSetNaN() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        String value = dfs.getNaN();
-        String value1 = value + "!";
-        dfs.setNaN(value1);
-        String result = dfs.getNaN();
-        assertNotEqual(value, result);
-        assertEquals(value1, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getMinusSign()'
-     */
-    public void testGetMinusSign() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        assertEquals('-', dfs.getMinusSign());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setMinusSign(char)'
-     */
-    public void testSetMinusSign() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        char value = dfs.getMinusSign();
-        char value1 = (char)(value + 1);
-        dfs.setMinusSign(value1);
-        char result = dfs.getMinusSign();
-        assertNotEqual(value, result);
-        assertEquals(value1, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getCurrencySymbol()'
-     */
-    public void testGetCurrencySymbol() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        assertEquals("$", dfs.getCurrencySymbol());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setCurrencySymbol(String)'
-     */
-    public void testSetCurrencySymbol() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        String value = dfs.getCurrencySymbol();
-        String value1 = value + "!";
-        dfs.setCurrencySymbol(value1);
-        String result = dfs.getCurrencySymbol();
-        assertNotEqual(value, result);
-        assertEquals(value1, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getInternationalCurrencySymbol()'
-     */
-    public void testGetInternationalCurrencySymbol() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        assertEquals("USD", dfs.getInternationalCurrencySymbol());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setInternationalCurrencySymbol(String)'
-     */
-    public void testSetInternationalCurrencySymbol() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        String value = dfs.getInternationalCurrencySymbol();
-        String value1 = value + "!";
-        dfs.setInternationalCurrencySymbol(value1);
-        String result = dfs.getInternationalCurrencySymbol();
-        assertNotEqual(value, result);
-        assertEquals(value1, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.getMonetaryDecimalSeparator()'
-     */
-    public void testGetMonetaryDecimalSeparator() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        assertEquals('.', dfs.getMonetaryDecimalSeparator());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.setMonetaryDecimalSeparator(char)'
-     */
-    public void testSetMonetaryDecimalSeparator() {
-        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.US);
-        char value = dfs.getMonetaryDecimalSeparator();
-        char value1 = (char)(value + 1);
-        dfs.setMonetaryDecimalSeparator(value1);
-        char result = dfs.getMonetaryDecimalSeparator();
-        assertNotEqual(value, result);
-        assertEquals(value1, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.clone()'
-     */
-    public void testClone() {
-        // tested in testHashcode
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormatSymbols.equals(Object)'
-     */
-    public void testEqualsObject() {
-        // tested in testHashcode
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatTest.java
deleted file mode 100644
index f32230a..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/DecimalFormatTest.java
+++ /dev/null
@@ -1,244 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2006-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.tests;
-
-import java.util.Locale;
-
-import com.ibm.icu.text.DecimalFormat;
-import com.ibm.icu.text.DecimalFormatSymbols;
-
-public class DecimalFormatTest extends ICUTestCase {
-    private static final long lmax = Long.MAX_VALUE;
-    private static final double dsmall = 23.33;
-        
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.clone()'
-     */
-    public void testClone() {
-        DecimalFormat df = new DecimalFormat("#,#0.00");
-        DecimalFormat df2 = new DecimalFormat("#,#0.00");
-        DecimalFormat dfn = new DecimalFormat("#,#0.00");
-        dfn.setNegativePrefix(dfn.getNegativePrefix() + '!');
-        testEHCS(df, df2, dfn);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.DecimalFormat(DecimalFormat)'
-     */
-    public void testDecimalFormatDecimalFormat() {
-        // tested implicitly
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.DecimalFormat()'
-     */
-    public void testDecimalFormat() {
-        DecimalFormat df = new DecimalFormat();
-        assertEquals("9,223,372,036,854,775,807", df.format(lmax));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.DecimalFormat(String)'
-     */
-    public void testDecimalFormatString() {
-        DecimalFormat df = new DecimalFormat("#,##0.000");
-        assertEquals("23.330", df.format(dsmall));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.DecimalFormat(String, DecimalFormatSymbols)'
-     */
-    public void testDecimalFormatStringDecimalFormatSymbols() {
-        DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.FRANCE);
-        DecimalFormat df = new DecimalFormat("#,##0.000", sym);
-        assertEquals("23,330", df.format(dsmall));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.getDecimalFormatSymbols()'
-     */
-    public void testGetDecimalFormatSymbols() {
-        DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.FRANCE);
-        DecimalFormat df = new DecimalFormat("#,##0.000", sym);
-        assertEquals(sym, df.getDecimalFormatSymbols());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.setDecimalFormatSymbols(DecimalFormatSymbols)'
-     */
-    public void testSetDecimalFormatSymbols() {
-        DecimalFormat df = new DecimalFormat();
-        df.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.FRANCE));
-        assertEquals("23,33", df.format(dsmall));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.getPositivePrefix()'
-     */
-    public void testGetPositivePrefix() {
-        DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#");
-        assertEquals("+", df.getPositivePrefix());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.setPositivePrefix(String)'
-     */
-    public void testSetPositivePrefix() {
-        DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#");
-        df.setPositivePrefix("?");
-        assertEquals("?23.3", df.format(dsmall));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.getNegativePrefix()'
-     */
-    public void testGetNegativePrefix() {
-        DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#");
-        assertEquals("-", df.getNegativePrefix());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.setNegativePrefix(String)'
-     */
-    public void testSetNegativePrefix() {
-        DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#");
-        df.setNegativePrefix("~");
-        assertEquals("~23.3", df.format(-dsmall));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.getPositiveSuffix()'
-     */
-    public void testGetPositiveSuffix() {
-        DecimalFormat df = new DecimalFormat("+#,##0.#**;-#,##0.#~~");
-        assertEquals("**", df.getPositiveSuffix());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.setPositiveSuffix(String)'
-     */
-    public void testSetPositiveSuffix() {
-        DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#");
-        df.setPositiveSuffix("**");
-        assertEquals("+23.3**", df.format(dsmall));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.getNegativeSuffix()'
-     */
-    public void testGetNegativeSuffix() {
-        DecimalFormat df = new DecimalFormat("+#,##0.#**;-#,##0.#~~");
-        assertEquals("~~", df.getNegativeSuffix());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.setNegativeSuffix(String)'
-     */
-    public void testSetNegativeSuffix() {
-        DecimalFormat df = new DecimalFormat("+#,##0.#;-#,##0.#");
-        df.setNegativeSuffix("~~");
-        assertEquals("-23.3~~", df.format(-dsmall));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.getMultiplier()'
-     */
-    public void testGetMultiplier() {
-        DecimalFormat df = new DecimalFormat("%000");
-        df.setMultiplier(1000);
-        assertEquals(1000, df.getMultiplier());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.setMultiplier(int)'
-     */
-    public void testSetMultiplier() {
-        DecimalFormat df = new DecimalFormat("%000");
-        assertEquals("%012", df.format(.123));
-        df.setMultiplier(1000);
-        assertEquals("%123", df.format(.123));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.getGroupingSize()'
-     */
-    public void testGetGroupingSize() {
-        DecimalFormat df = new DecimalFormat("#,#0.#");
-        assertEquals(2, df.getGroupingSize());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.setGroupingSize(int)'
-     */
-    public void testSetGroupingSize() {
-        DecimalFormat df = new DecimalFormat("#,##0.##");
-        assertEquals("1,234,567.89", df.format(1234567.89));
-        df.setGroupingSize(2);
-        assertEquals("1,23,45,67.89", df.format(1234567.89));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.isDecimalSeparatorAlwaysShown()'
-     */
-    public void testIsDecimalSeparatorAlwaysShown() {
-        DecimalFormat df = new DecimalFormat("#.#");
-        df.setDecimalSeparatorAlwaysShown(false);
-        assertEquals("1", df.format(1));
-        assertEquals("1.2", df.format(1.2));
-        df.setDecimalSeparatorAlwaysShown(true);
-        assertEquals("1.", df.format(1));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.setDecimalSeparatorAlwaysShown(boolean)'
-     */
-    public void testSetDecimalSeparatorAlwaysShown() {
-        DecimalFormat df = new DecimalFormat("#.#");
-        df.setDecimalSeparatorAlwaysShown(false);
-        assertFalse(df.isDecimalSeparatorAlwaysShown());
-        df.setDecimalSeparatorAlwaysShown(true);
-        assertTrue(df.isDecimalSeparatorAlwaysShown());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.toPattern()'
-     */
-    public void testToPattern() {
-        DecimalFormat df = new DecimalFormat("#,##0.##");
-        assertEquals("#,##0.##", df.toPattern());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.toLocalizedPattern()'
-     */
-    public void testToLocalizedPattern() {
-        DecimalFormat df = new DecimalFormat("#,##0.##", new DecimalFormatSymbols(Locale.FRANCE));
-        assertEquals("#,##0.##", df.toPattern());
-        assertEquals("#\u00a0##0,##", df.toLocalizedPattern());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.applyPattern(String)'
-     */
-    public void testApplyPattern() {
-        DecimalFormat df = new DecimalFormat("#,##0.##");
-        df.applyPattern("#,0.#");
-        assertEquals("1,2,3.4", df.format(123.4));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.DecimalFormat.applyLocalizedPattern(String)'
-     */
-    public void testApplyLocalizedPattern() {
-        DecimalFormat df = new DecimalFormat("#,##0.##", new DecimalFormatSymbols(Locale.FRANCE));
-        df.applyLocalizedPattern("#\u00a00,#");
-        assertEquals("1\u00a02\u00a03,4", df.format(123.4));
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ICUTestCase.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ICUTestCase.java
deleted file mode 100644
index e053d1c..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ICUTestCase.java
+++ /dev/null
@@ -1,288 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2006-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.tests;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.lang.reflect.Array;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Locale;
-
-import com.ibm.icu.util.TimeZone;
-import com.ibm.icu.util.ULocale;
-
-import junit.framework.TestCase;
-
-/**
- * Implement boilerplate tests.
- * Currently there is only one method, testEHCS, which tests equals, hashCode, 
- * clone, and serialization.
- */
-public abstract class ICUTestCase extends TestCase {
-    private static final Object[] EMPTY_ARGS = {};
-	private static final Class<?>[] EMPTY_CLASSES = {};
-        
-    private static final Locale oldLocale = Locale.getDefault();
-    private static final ULocale oldULocale = ULocale.getDefault();
-    private static final java.util.TimeZone oldJTimeZone = java.util.TimeZone.getDefault();
-    private static final TimeZone oldITimeZone = TimeZone.getDefault();
-                
-    // TODO: what's the best way to check this?
-    public static final boolean testingWrapper = true;
-
-    protected void setUp() throws Exception {
-        super.setUp();
-        Locale.setDefault(Locale.US);
-        ULocale.setDefault(ULocale.US);
-        java.util.TimeZone.setDefault(java.util.TimeZone.getTimeZone("PST"));
-        TimeZone.setDefault(TimeZone.getTimeZone("PST"));
-    }
-        
-    protected void tearDown() throws Exception {
-        ULocale.setDefault(oldULocale);
-        Locale.setDefault(oldLocale);
-        TimeZone.setDefault(oldITimeZone);
-        java.util.TimeZone.setDefault(oldJTimeZone);
-        super.tearDown();
-    }
-
-    private static final Object test = new Object();
-        
-    /**
-     * Assert that two objects are _not_ equal.  Curiously missing from Assert.
-     * @param lhs an object to test, may be null
-     * @param rhs an object to test, may be null
-     */
-    public static void assertNotEqual(Object lhs, Object rhs) {
-        if (lhs == null) {
-            if (rhs == null) fail("null equals null");
-        } else {
-            if (lhs.equals(rhs)) {
-                fail(lhs.toString() + " equals " + rhs);
-            }
-        }
-    }
-        
-    public static void assertNotEqual(long lhs, long rhs) {
-        if (lhs == rhs) {
-            fail("values are equal: " + lhs);
-        }
-    }
-        
-    /**
-     * Test whether equality, hashCode, clone, and serialization work as expected.  
-     * Equals(Object) is assumed to return false (not throw an exception) if passed 
-     * null or an object of an incompatible class.
-     * Hashcodes must be equal iff the two objects compare equal.  No attempt is made to
-     * evaluate the quality of the hashcode distribution, so (in particular) degenerate 
-     * hashcode implementations will pass this test.
-     * Clone will be tested if the method "clone" is public on the class of obj.  
-     * It is assumed to return an object that compares equal to obj.
-     * Serialization will be tested if object implements Serializable or Externalizable.
-     * It is assumed the serialized/deserialized object compares equal to obj.
-     * @param obj the object to test
-     * @param eq an object that should compare equal to, but is not the same as, obj.  
-     *     it should be assignable to the class of obj.
-     * @param neq a non-null object that should not compare equal to obj.  
-     *     it should be assignable to the class of obj.
-     */
-	public static void testEHCS(Object obj, Object eq, Object neq) {
-        if (obj == null || eq == null || neq == null) {
-            throw new NullPointerException();
-        }
-        Class<? extends Object> cls = obj.getClass();
-        if (!(cls.isAssignableFrom(eq.getClass()) && cls.isAssignableFrom(neq.getClass()))) {
-            throw new IllegalArgumentException("unassignable classes");
-        }
-                
-        // reflexive
-        assertEquals(obj, obj);
-                
-        // should return false, not throw exception
-        assertNotEqual(obj, test);
-        assertNotEqual(obj, null);
-                
-        // commutative
-        assertEquals(obj, eq);
-        assertEquals(eq, obj);
-                
-        assertNotEqual(obj, neq);
-        assertNotEqual(neq, obj);
-                
-        // equal objects MUST have equal hashes, unequal objects MAY have equal hashes
-        assertEquals(obj.hashCode(), eq.hashCode());
-                
-        Object clone = null;
-        try {
-            // look for public clone method and call it if available
-            Method method_clone = cls.getMethod("clone", EMPTY_CLASSES);
-            clone = method_clone.invoke(obj, EMPTY_ARGS);
-            assertNotNull(clone);
-        }
-        catch(NoSuchMethodException e) {
-            // ok
-        }
-        catch(InvocationTargetException e) {
-            // ok
-        }
-        catch(IllegalAccessException e) {
-            // ok
-        }
-                
-        if (clone != null) {
-            assertEquals(obj, clone);
-            assertEquals(clone, obj);
-        }
-                
-        if (obj instanceof Serializable || obj instanceof Externalizable) {
-            Object ser = null;
-            try {
-                ByteArrayOutputStream bos = new ByteArrayOutputStream();
-                ObjectOutputStream oos = new ObjectOutputStream(bos);
-                oos.writeObject(clone);
-                oos.close();
-                                
-                ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
-                ObjectInputStream ois = new ObjectInputStream(bis);
-                ser = ois.readObject();
-                ois.close();
-            }
-            catch(IOException e) {
-                System.err.println(e.getMessage());
-                throw new RuntimeException(e);
-            }
-            catch(ClassNotFoundException e) {
-                System.err.println(e.getMessage());
-                throw new RuntimeException(e);
-            }
-                        
-            if (ser != null) {
-                assertEquals(obj, ser);
-                assertEquals(ser, obj);
-                assertEquals(obj.hashCode(), ser.hashCode());
-            }
-        }
-    }
-
-    /**
-     * Fail if the arrays are not equal.  To be equal, the arrays must
-     * be the same length, and each element in the left array must compare
-     * equal to the corresponding element of the right array.
-     * Also fails if one of the objects is not an array.
-     * @param lhs the left array
-     * @param rhs the right array
-     */
-    public static void assertArraysEqual(Object lhs, Object rhs) {
-        Class<? extends Object> lcls = lhs.getClass();
-        Class<? extends Object> rcls = rhs.getClass();
-        if (!(lcls.isArray() && rcls.isArray())) {
-            fail("objects are not arrays");
-        }
-        String result = arraysAreEqual(lhs, rhs);
-        if (result != null) {
-            fail(result);
-        }
-    }
-
-    /**
-     * Fail if the arrays are equal.  Also fails if one or the other 
-     * argument is not an array.
-     * @param lhs the left array
-     * @param rhs the right array
-     */
-    public static void assertArraysNotEqual(Object lhs, Object rhs) {
-        Class<? extends Object> lcls = lhs.getClass();
-        Class<? extends Object> rcls = rhs.getClass();
-        if (!(lcls.isArray() && rcls.isArray())) {
-            fail("objects are not arrays");
-        }
-        String result = arraysAreEqual(lhs, rhs);
-        if (result == null) {
-            fail("arrays are equal");
-        }
-    }
-        
-    // slow but general
-    private static String arraysAreEqual(Object lhsa, Object rhsa) {
-        int lhsl = Array.getLength(lhsa);
-        int rhsl = Array.getLength(rhsa);
-        if (lhsl != rhsl) {
-            return "length " + lhsl + " != " + rhsl;
-        }
-        boolean lhsaA = lhsa.getClass().getComponentType().isArray();
-        boolean rhsaA = rhsa.getClass().getComponentType().isArray();
-        if (lhsaA != rhsaA) {
-            return (lhsaA ? "" : "non-") + "array != " + (rhsaA ? "" : "non-") + "array";
-        }
-        for (int i = 0; i < lhsl; ++i) {
-            Object lhse = Array.get(lhsa, i);
-            Object rhse = Array.get(rhsa, i);
-            if (lhse == null) {
-                if (rhse != null) {
-                    return "null != " + rhse;
-                }
-            } else {
-                if (lhsaA) {
-                    String result = arraysAreEqual(lhse, rhse);
-                    if (result != null) {
-                        if (result.charAt(0) != '[') {
-                            result = " " + result;
-                        }
-                        return "[" + i + "]" + result;
-                    }
-                } else {
-                    if (!lhse.equals(rhse)) {
-                        return lhse.toString() + " != " + rhse;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-        
-    // much more painful and slow than it should be... partly because of the
-    // oddness of clone, partly because arrays don't provide a Method for 
-    // 'clone' despite the fact that they implement it and make it public.
-    public static Object cloneComplex(Object obj) {
-        Object result = null;
-        if (obj != null) {
-            Class<? extends Object> cls = obj.getClass();
-            if (cls.isArray()) {
-                int len = Array.getLength(obj);
-                Class<?> typ = cls.getComponentType();
-                result = Array.newInstance(typ, len);
-                boolean prim = typ.isPrimitive();
-                for (int i = 0; i < len; ++i) {
-                    Object elem = Array.get(obj, i);
-                    Array.set(result, i, prim ? elem : cloneComplex(elem));
-                }
-            } else {
-                result = obj; // default
-                try {
-                    Method cloneM = cls.getMethod("clone", EMPTY_CLASSES);
-                    result = cloneM.invoke(obj, EMPTY_ARGS);
-                }
-                catch (NoSuchMethodException e) {
-                }
-                catch (IllegalAccessException e) {
-                }
-                catch (InvocationTargetException e) {
-                }
-            }
-        }
-        return result;
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/MessageFormatTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/MessageFormatTest.java
deleted file mode 100644
index fb6f327..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/MessageFormatTest.java
+++ /dev/null
@@ -1,309 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2006-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.tests;
-
-import java.text.FieldPosition;
-import java.text.Format;
-import java.text.ParseException;
-import java.text.ParsePosition;
-import java.util.Date;
-import java.util.Locale;
-
-import com.ibm.icu.text.DateFormat;
-import com.ibm.icu.text.MessageFormat;
-import com.ibm.icu.text.NumberFormat;
-import com.ibm.icu.util.ULocale;
-
-public class MessageFormatTest extends ICUTestCase {
-    private final String pattern = "Deleted {0,number} files at {1,time,short} on {1,date}.";
-    private final String altPattern = "Deleted {0,  number } files at {1, time, short} on {1, date}.";
-    private final Date date = new Date(716698890835L);
-    private final Number num = new Long(3456);
-    private final Object[] args = { num, date };
-    private final Date dateOnly = new Date(716626800000L);
-    private final String englishTarget = "Deleted 3,456 files at 8:01 PM on Sep 16, 1992.";
-    private final String germanTarget = "Deleted 3.456 files at 20:01 on 16.09.1992.";
-    private final String modifiedTarget = "Deleted 3,456 files at 8:01:30 PM PDT on Sep 16, 1992.";
-    
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.hashCode()'
-     */
-    public void testHashCode() {
-        MessageFormat mf = new MessageFormat(pattern);
-        MessageFormat eq = new MessageFormat(altPattern);
-        MessageFormat ne = new MessageFormat("Deleted (0, number, currency} files at {1, time} on {1, date}.");
-        testEHCS(mf, eq, ne);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.MessageFormat(MessageFormat)'
-     */
-    public void testMessageFormatMessageFormat() {
-        // implicitly tested everywhere
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.MessageFormat(String)'
-     */
-    public void testMessageFormatString() {
-        MessageFormat mf = new MessageFormat(pattern);
-        assertEquals(englishTarget, mf.format(args));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.MessageFormat(String, Locale)'
-     */
-    public void testMessageFormatStringLocale() {
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        assertEquals(englishTarget, mf.format(args));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.MessageFormat(String, ULocale)'
-     */
-    public void testMessageFormatStringULocale() {
-        MessageFormat mf = new MessageFormat(pattern, ULocale.US);
-        assertEquals(englishTarget, mf.format(args));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.setLocale(Locale)'
-     */
-    public void testSetLocaleLocale() {
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        mf.setLocale(Locale.GERMANY);
-        mf.applyPattern(pattern);
-        assertEquals(germanTarget, mf.format(args));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.setLocale(ULocale)'
-     */
-    public void testSetLocaleULocale() {
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        mf.setLocale(ULocale.GERMANY);
-        mf.applyPattern(pattern);
-        assertEquals(germanTarget, mf.format(args));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.getLocale()'
-     */
-    public void testGetLocale() {
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        mf.setLocale(Locale.GERMANY);
-        assertEquals(Locale.GERMANY, mf.getLocale());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.getULocale()'
-     */
-    public void testGetULocale() {
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        mf.setLocale(ULocale.GERMANY);
-        assertEquals(ULocale.GERMANY, mf.getULocale());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.applyPattern(String)'
-     */
-    public void testApplyPattern() {
-        MessageFormat mf = new MessageFormat("foo");
-        mf.applyPattern(pattern);
-        assertEquals(englishTarget, mf.format(args));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.toPattern()'
-     */
-    public void testToPattern() {
-        MessageFormat mf = new MessageFormat(altPattern);
-        assertEquals(pattern, mf.toPattern());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.setFormatsByArgumentIndex(Format[])'
-    public void testSetFormatsByArgumentIndex() {
-        // this api is broken.  if the same argument is used twice with two different
-        // formats, this can't be used, since it sets only one format per argument.
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        Format[] formats = {
-            NumberFormat.getIntegerInstance(),
-            DateFormat.getTimeInstance(DateFormat.SHORT),
-            DateFormat.getDateInstance(),
-        };
-        mf.setFormatsByArgumentIndex(formats);
-        assertEquals(brokenButConformantTarget, mf.format(args));
-    }
-     */
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.setFormats(Format[])'
-     */
-    public void testSetFormats() {
-        // this api, while it has the problem that the order of formats depends
-        // on the order in the string, at least lets you set all the formats.
-        
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        Format[] formats = {
-            NumberFormat.getIntegerInstance(),
-            DateFormat.getTimeInstance(DateFormat.SHORT),
-            DateFormat.getDateInstance(),
-        };
-        mf.setFormats(formats);
-        assertEquals(englishTarget, mf.format(args));
-   }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.setFormatByArgumentIndex(int, Format)'
-     public void testSetFormatByArgumentIndex() {
-        // same problem, once you set a format for an argument, you've set all of them
-        
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        mf.setFormatByArgumentIndex(1, DateFormat.getTimeInstance(DateFormat.SHORT));
-        assertEquals(brokenButConformantTarget, mf.format(args));
-
-    }
-    */
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.setFormat(int, Format)'
-     */
-    public void testSetFormat() {
-        // and ok again        
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        mf.setFormat(1, DateFormat.getTimeInstance(DateFormat.LONG));
-        assertEquals(modifiedTarget, mf.format(args));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.getFormatsByArgumentIndex()'
-    public void testGetFormatsByArgumentIndex() {
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        Format[] formats = mf.getFormatsByArgumentIndex();
-        NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
-        assertEquals(formats[0], nf);
-        DateFormat df = DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.US);
-        assertEquals(formats[1], df);
-    }
-     */
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.getFormats()'
-     */
-    public void testGetFormats() {
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        Format[] formats = mf.getFormats();
-        NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
-        assertEquals(formats[0], nf);
-        DateFormat tf = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.US);
-        assertEquals(formats[1], tf);
-        DateFormat df = DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.US);
-        assertEquals(formats[2], df);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.format(Object[], StringBuffer, FieldPosition)'
-     */
-    public void testFormatObjectArrayStringBufferFieldPosition() {
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        StringBuffer buf = new StringBuffer();
-        FieldPosition fp = new FieldPosition(0);
-        mf.format(args, buf, fp);
-        assertEquals(englishTarget, buf.toString());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.format(String, Object[])'
-     */
-    public void testFormatStringObjectArray() {
-        assertEquals(englishTarget, MessageFormat.format(pattern, args));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.format(Object, StringBuffer, FieldPosition)'
-     */
-    public void testFormatObjectStringBufferFieldPosition() {
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        StringBuffer buf = new StringBuffer();
-        FieldPosition fp = new FieldPosition(0);
-        mf.format((Object)args, buf, fp);
-        assertEquals(englishTarget, buf.toString());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.parse(String, ParsePosition)'
-     */
-    public void testParseStringParsePosition() {
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        ParsePosition pp = new ParsePosition(1);
-        Object[] result = mf.parse("!" + englishTarget, pp);
-        assertEquals(num, result[0]);
-        assertEquals(dateOnly, result[1]);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.parse(String)'
-     */
-    public void testParseString() {
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        try {
-            Object[] result = mf.parse(englishTarget);
-            assertEquals(num, result[0]);
-            assertEquals(dateOnly, result[1]);
-        }
-        catch (ParseException e) {
-            fail(e.getMessage());
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.parseObject(String, ParsePosition)'
-     */
-    public void testParseObjectStringParsePosition() {
-        MessageFormat mf = new MessageFormat(pattern, Locale.US);
-        ParsePosition pp = new ParsePosition(0);
-        Object result = mf.parseObject(englishTarget, pp);
-        assertEquals(num, ((Object[])result)[0]);
-        assertEquals(dateOnly, ((Object[])result)[1]);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.autoQuoteApostrophe(String)'
-     */
-    public void testAutoQuoteApostrophe() {
-        String str = "Let's meet at {1,time,h 'o'' clock'} at l'Orange Bleue";
-        String pat = MessageFormat.autoQuoteApostrophe(str);
-        MessageFormat mf = new MessageFormat(pat, Locale.US);
-        String result = mf.format(args);
-        assertEquals("Let's meet at 8 o' clock at l'Orange Bleue", result);
-        assertEquals("Let''s meet at {1,time,h 'o'' clock'} at l''Orange Bleue", pat);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.clone()'
-     */
-    public void testClone() {
-        // tested already in testHashcode
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.equals(Object)'
-     */
-    public void testEqualsObject() {
-        // tested already in testHashcode
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.MessageFormat.toString()'
-     */
-    public void testToString() {
-        // no need to test
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/NumberFormatTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/NumberFormatTest.java
deleted file mode 100644
index 931fa7d..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/NumberFormatTest.java
+++ /dev/null
@@ -1,449 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2007-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.tests;
-
-import java.math.BigInteger;
-import java.text.FieldPosition;
-import java.text.ParseException;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-import com.ibm.icu.text.NumberFormat;
-import com.ibm.icu.util.ULocale;
-
-public class NumberFormatTest extends ICUTestCase {
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.NumberFormat(NumberFormat)'
-     */
-    public void testNumberFormat() {
-        NumberFormat nf = new NumberFormat(java.text.NumberFormat.getInstance());
-        assertEquals(nf, NumberFormat.getInstance());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.format(Object, StringBuffer, FieldPosition)'
-     */
-    public void testFormatObjectStringBufferFieldPosition() {
-        Number num = new Long(1234L);
-        StringBuffer buf = new StringBuffer();
-        FieldPosition fp = new FieldPosition(NumberFormat.INTEGER_FIELD);
-        NumberFormat.getInstance().format(num, buf, fp);
-        assertEquals("1,234", buf.toString());
-        assertEquals(0, fp.getBeginIndex());
-        assertEquals(5, fp.getEndIndex());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.parseObject(String, ParsePosition)'
-     */
-    public void testParseObjectStringParsePosition() {
-        ParsePosition pp = new ParsePosition(0);
-        Object result = NumberFormat.getInstance().parse("1,234", pp);
-        assertEquals(result, new Long(1234));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.format(double)'
-     */
-    public void testFormatDouble() {
-        assertEquals("1,234.567", NumberFormat.getInstance().format(1234.567));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.format(long)'
-     */
-    public void testFormatLong() {
-        assertEquals("1,234", NumberFormat.getInstance().format(1234L));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.format(BigInteger)'
-     */
-    public void testFormatBigInteger() {
-        // note, java doesn't handle biginteger with full precision.
-        BigInteger bi = new BigInteger("123456");
-        assertEquals("123,456", java.text.NumberFormat.getInstance().format(bi));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.format(double, StringBuffer, FieldPosition)'
-     */
-    public void testFormatDoubleStringBufferFieldPosition() {
-        StringBuffer buf = new StringBuffer();
-        FieldPosition fp = new FieldPosition(NumberFormat.FRACTION_FIELD);
-        assertEquals("123,456.789", NumberFormat.getInstance().format(123456.789, buf, fp).toString());
-        assertEquals(8, fp.getBeginIndex());
-        assertEquals(11, fp.getEndIndex());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.format(long, StringBuffer, FieldPosition)'
-     */
-    public void testFormatLongStringBufferFieldPosition() {
-        StringBuffer buf = new StringBuffer();
-        FieldPosition fp = new FieldPosition(NumberFormat.Field.GROUPING_SEPARATOR);
-        assertEquals("123,456", NumberFormat.getInstance().format(123456L, buf, fp).toString());
-        assertEquals(3, fp.getBeginIndex());
-        assertEquals(4, fp.getEndIndex());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.format(BigInteger, StringBuffer, FieldPosition)'
-     */
-    public void testFormatBigIntegerStringBufferFieldPosition() {
-        // note, java doesn't handle biginteger with full precision.
-        StringBuffer buf = new StringBuffer();
-        FieldPosition fp = new FieldPosition(0);
-        BigInteger bi = new BigInteger("123456");
-        assertEquals("123,456", java.text.NumberFormat.getInstance().format(bi, buf, fp).toString());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.parse(String, ParsePosition)'
-     */
-    public void testParseStringParsePosition() {
-        ParsePosition pp = new ParsePosition(3);
-        assertEquals(new Long(123456), NumberFormat.getInstance().parse("xxx123,456yyy", pp));
-        assertEquals(10, pp.getIndex());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.parse(String)'
-     */
-    public void testParseString() throws ParseException {
-        Number result = NumberFormat.getInstance().parse("123,456,yyy");
-        assertEquals(new Long(123456), result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.isParseIntegerOnly()'
-     */
-    public void testIsParseIntegerOnly() {
-        NumberFormat nf = NumberFormat.getInstance();
-        nf.setParseIntegerOnly(true);
-        assertTrue(nf.isParseIntegerOnly());
-        nf.setParseIntegerOnly(false);
-        assertFalse(nf.isParseIntegerOnly());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.setParseIntegerOnly(boolean)'
-     */
-    public void testSetParseIntegerOnly() throws ParseException {
-        String str = "123.456,yyy";
-        NumberFormat nf = NumberFormat.getInstance();
-        assertEquals(new Double(123.456), nf.parse(str));
-        nf.setParseIntegerOnly(true);
-        assertEquals(new Long(123), nf.parse(str));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getInstance()'
-     */
-    public void testGetInstance() {
-        // used everywhere, no need to test
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getInstance(Locale)'
-     */
-    public void testGetInstanceLocale() {
-        NumberFormat nf = NumberFormat.getInstance(Locale.GERMANY);
-        assertEquals("123,456", nf.format(123.456));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getInstance(ULocale)'
-     */
-    public void testGetInstanceULocale() {
-        NumberFormat nf = NumberFormat.getInstance(ULocale.GERMANY);
-        assertEquals("123,456", nf.format(123.456));            
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getNumberInstance()'
-     */
-    public void testGetNumberInstance() {
-        NumberFormat nf = NumberFormat.getNumberInstance();
-        assertEquals("123,456.789", nf.format(123456.789));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getNumberInstance(Locale)'
-     */
-    public void testGetNumberInstanceLocale() {
-        NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMANY);
-        assertEquals("123.456,789", nf.format(123456.789));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getNumberInstance(ULocale)'
-     */
-    public void testGetNumberInstanceULocale() {
-        NumberFormat nf = NumberFormat.getNumberInstance(ULocale.GERMANY);
-        assertEquals("123.456,789", nf.format(123456.789));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getIntegerInstance()'
-     */
-    public void testGetIntegerInstance() {
-        NumberFormat nf = NumberFormat.getIntegerInstance();
-        assertEquals("123,457", nf.format(123456.789)); // rounds
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getIntegerInstance(Locale)'
-     */
-    public void testGetIntegerInstanceLocale() {
-        NumberFormat nf = NumberFormat.getIntegerInstance(Locale.GERMANY);
-        assertEquals("123.457", nf.format(123456.789)); // rounds
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getIntegerInstance(ULocale)'
-     */
-    public void testGetIntegerInstanceULocale() {
-        NumberFormat nf = NumberFormat.getIntegerInstance(ULocale.GERMANY);
-        assertEquals("123.457", nf.format(123456.789)); // rounds
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getCurrencyInstance()'
-     */
-    public void testGetCurrencyInstance() {
-        NumberFormat nf = NumberFormat.getCurrencyInstance();
-        assertEquals("$123,456.99", nf.format(123456.99));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getCurrencyInstance(Locale)'
-     */
-    public void testGetCurrencyInstanceLocale() {
-        NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.GERMANY);
-        assertEquals("123.456,99 \u20AC", nf.format(123456.99));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getCurrencyInstance(ULocale)'
-     */
-    public void testGetCurrencyInstanceULocale() {
-        NumberFormat nf = NumberFormat.getCurrencyInstance(ULocale.GERMANY);
-        assertEquals("123.456,99 \u20AC", nf.format(123456.99));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getPercentInstance()'
-     */
-    public void testGetPercentInstance() {
-        NumberFormat nf = NumberFormat.getPercentInstance();
-        assertEquals("123,456%", nf.format(1234.56));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getPercentInstance(Locale)'
-     */
-    public void testGetPercentInstanceLocale() {
-        NumberFormat nf = NumberFormat.getPercentInstance(Locale.GERMANY);
-        assertEquals("123.456%", nf.format(1234.56));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getPercentInstance(ULocale)'
-     */
-    public void testGetPercentInstanceULocale() {
-        NumberFormat nf = NumberFormat.getPercentInstance(ULocale.GERMANY);
-        assertEquals("123.456%", nf.format(1234.56));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getScientificInstance()'
-     */
-    public void testGetScientificInstance() {
-        NumberFormat nf = NumberFormat.getScientificInstance();
-        assertEquals(".123456E4", nf.format(1234.56));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getScientificInstance(Locale)'
-     */
-    public void testGetScientificInstanceLocale() {
-        NumberFormat nf = NumberFormat.getScientificInstance(Locale.GERMANY);
-        assertEquals(",123456E4", nf.format(1234.56));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getScientificInstance(ULocale)'
-     */
-    public void testGetScientificInstanceULocale() {
-        NumberFormat nf = NumberFormat.getScientificInstance(ULocale.GERMANY);
-        assertEquals(",123456E4", nf.format(1234.56));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getAvailableLocales()'
-     */
-    public void testGetAvailableLocales() {
-        Locale[] ilocales = NumberFormat.getAvailableLocales();
-        if (ICUTestCase.testingWrapper) {
-            Locale[] jlocales = java.text.NumberFormat.getAvailableLocales();
-            for (int i = 0; i < ilocales.length; ++i) {
-                assertEquals(jlocales[i], ilocales[i]);
-            }
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getAvailableULocales()'
-     */
-    public void testGetAvailableULocales() {
-        ULocale[] ulocales = NumberFormat.getAvailableULocales();
-        if (ICUTestCase.testingWrapper) {
-            Locale[] jlocales = java.text.NumberFormat.getAvailableLocales();
-            for (int i = 0; i < ulocales.length; ++i) {
-                assertEquals(jlocales[i], ulocales[i].toLocale());
-            }
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.isGroupingUsed()'
-     */
-    public void testIsGroupingUsed() {
-        NumberFormat nf = NumberFormat.getInstance();
-        nf.setGroupingUsed(true);
-        assertTrue(nf.isGroupingUsed());
-        nf.setGroupingUsed(false);
-        assertFalse(nf.isGroupingUsed());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.setGroupingUsed(boolean)'
-     */
-    public void testSetGroupingUsed() {
-        NumberFormat nf = NumberFormat.getInstance();
-        assertEquals("123,456,789", nf.format(123456789));
-        nf.setGroupingUsed(false);
-        assertEquals("123456789", nf.format(123456789));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getMaximumIntegerDigits()'
-     */
-    public void testGetMaximumIntegerDigits() {
-        NumberFormat nf = NumberFormat.getInstance();
-        nf.setMaximumIntegerDigits(4);
-        assertEquals(4, nf.getMaximumIntegerDigits());
-        nf.setMaximumIntegerDigits(6);
-        assertEquals(6, nf.getMaximumIntegerDigits());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.setMaximumIntegerDigits(int)'
-     */
-    public void testSetMaximumIntegerDigits() {
-        NumberFormat nf = NumberFormat.getInstance();
-        nf.setMaximumIntegerDigits(4);
-        assertEquals("3,456", nf.format(123456)); // high digits truncated
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getMinimumIntegerDigits()'
-     */
-    public void testGetMinimumIntegerDigits() {
-        NumberFormat nf = NumberFormat.getInstance();
-        nf.setMinimumIntegerDigits(4);
-        assertEquals(4, nf.getMinimumIntegerDigits());
-        nf.setMinimumIntegerDigits(6);
-        assertEquals(6, nf.getMinimumIntegerDigits());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.setMinimumIntegerDigits(int)'
-     */
-    public void testSetMinimumIntegerDigits() {
-        NumberFormat nf = NumberFormat.getInstance();
-        nf.setMinimumIntegerDigits(4);
-        assertEquals("0,012", nf.format(12)); // pad out with zero, grouping still used
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getMaximumFractionDigits()'
-     */
-    public void testGetMaximumFractionDigits() {
-        NumberFormat nf = NumberFormat.getInstance();
-        nf.setMaximumFractionDigits(4);
-        assertEquals(4, nf.getMaximumFractionDigits());
-        nf.setMaximumFractionDigits(6);
-        assertEquals(6, nf.getMaximumFractionDigits());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.setMaximumFractionDigits(int)'
-     */
-    public void testSetMaximumFractionDigits() {
-        NumberFormat nf = NumberFormat.getInstance();
-        nf.setMaximumFractionDigits(4);
-        assertEquals("1.2346", nf.format(1.2345678)); // low digits rounded
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.getMinimumFractionDigits()'
-     */
-    public void testGetMinimumFractionDigits() {
-        NumberFormat nf = NumberFormat.getInstance();
-        nf.setMinimumFractionDigits(4);
-        assertEquals(4, nf.getMinimumFractionDigits());
-        nf.setMinimumFractionDigits(6);
-        assertEquals(6, nf.getMinimumFractionDigits());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.setMinimumFractionDigits(int)'
-     */
-    public void testSetMinimumFractionDigits() {
-        NumberFormat nf = NumberFormat.getInstance();
-        nf.setMinimumFractionDigits(4);
-        assertEquals("1.2000", nf.format(1.2));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.toString()'
-     */
-    public void testToString() {
-        assertNotNull(NumberFormat.getInstance().toString());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.hashCode()'
-     */
-    public void testHashCode() {
-        NumberFormat nf = NumberFormat.getInstance();
-        NumberFormat eq = NumberFormat.getInstance(Locale.US);
-        NumberFormat neq = NumberFormat.getInstance(Locale.GERMANY);
-                
-        ICUTestCase.testEHCS(nf, eq, neq);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.clone()'
-     */
-    public void testClone() {
-        // see testHashCode
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.text.NumberFormat.equals(Object)'
-     */
-    public void testEqualsObject() {
-        // see testHashCode
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/SimpleDateFormatTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/SimpleDateFormatTest.java
deleted file mode 100644
index 1ddc240..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/SimpleDateFormatTest.java
+++ /dev/null
@@ -1,204 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2006-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.tests;
-
-import java.text.FieldPosition;
-import java.text.ParseException;
-import java.text.ParsePosition;
-import java.util.Date;
-import java.util.Locale;
-
-import com.ibm.icu.text.DateFormatSymbols;
-import com.ibm.icu.text.SimpleDateFormat;
-import com.ibm.icu.util.Calendar;
-import com.ibm.icu.util.TimeZone;
-import com.ibm.icu.util.ULocale;
-
-public class SimpleDateFormatTest extends ICUTestCase {
-    private static final String mdy = "MMM dd yyyy";
-    private static final String md2 = "MMM dd yy";
-    private static final String hmz = "'The time is' HH:mm:ss zzz";
-    private static final String hmzmdy = hmz + " 'on' " + mdy;
-    private static final String hmzmdyStr = "The time is 15:05:20 CST on Jan 10 2006";
-        
-    private static final TimeZone tzc = TimeZone.getTimeZone("CST");
-    private static final TimeZone tzp = TimeZone.getTimeZone("PST");
-    private static final Calendar cal = Calendar.getInstance(tzc);
-    private static final Date date;
-    static {
-        cal.clear();
-        cal.set(2006, 0, 10, 15, 5, 20); // arrgh, doesn't clear millis
-        date = cal.getTime();
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.format(Calendar, StringBuffer, FieldPosition)'
-     */
-    public void testFormatCalendarStringBufferFieldPosition() {
-        StringBuffer buf = new StringBuffer();
-        FieldPosition fp = new FieldPosition(0);
-        SimpleDateFormat sdf = new SimpleDateFormat(hmzmdy);
-        sdf.format(cal, buf, fp);
-        assertEquals(hmzmdyStr, buf.toString());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.parse(String, Calendar, ParsePosition)'
-     */
-    public void testParseStringCalendarParsePosition() {
-        Calendar cal = Calendar.getInstance(tzp);
-        cal.clear();
-        ParsePosition pp = new ParsePosition(0);
-        SimpleDateFormat sdf = new SimpleDateFormat(hmzmdy);
-        sdf.parse(hmzmdyStr, cal, pp);
-        assertEquals(date, cal.getTime());
-        // note: java doesn't return the parsed time zone
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.clone()'
-     */
-    public void testClone() {
-
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat()'
-     */
-    public void testSimpleDateFormat() {
-        SimpleDateFormat sdf = new SimpleDateFormat();
-        java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat();
-        assertEquals(jsdf.format(date), sdf.format(date));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String)'
-     */
-    public void testSimpleDateFormatString() {
-        SimpleDateFormat sdf = new SimpleDateFormat(mdy);
-        java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy);
-        assertEquals(jsdf.format(date), sdf.format(date));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String, Locale)'
-     */
-    public void testSimpleDateFormatStringLocale() {
-        Locale l = Locale.JAPAN;
-        SimpleDateFormat sdf = new SimpleDateFormat(mdy, l);
-        java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy, l);
-        assertEquals(jsdf.format(date), sdf.format(date));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String, ULocale)'
-     */
-    public void testSimpleDateFormatStringULocale() {
-        ULocale l = ULocale.JAPAN;
-        SimpleDateFormat sdf = new SimpleDateFormat(mdy, l);
-        java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy, l.toLocale());
-        assertEquals(jsdf.format(date), sdf.format(date));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.SimpleDateFormat(String, DateFormatSymbols)'
-     */
-    public void testSimpleDateFormatStringDateFormatSymbols() {
-        Locale l = Locale.US;
-        DateFormatSymbols dfs = new DateFormatSymbols(l);
-        java.text.DateFormatSymbols jdfs = new java.text.DateFormatSymbols(l);
-        SimpleDateFormat sdf = new SimpleDateFormat(mdy, dfs);
-        java.text.SimpleDateFormat jsdf = new java.text.SimpleDateFormat(mdy, jdfs);
-        assertEquals(jsdf.format(date), sdf.format(date));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.set2DigitYearStart(Date)'
-     */
-    public void testSet2DigitYearStart() {
-        SimpleDateFormat sdf = new SimpleDateFormat(md2);
-        sdf.set2DigitYearStart(date);
-        try {
-            Date d = sdf.parse("Jan 15 04");
-            assertNotEqual(-1, d.toString().indexOf("2104"));
-        }
-        catch (ParseException pe) {
-            fail(pe.getMessage());
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.get2DigitYearStart()'
-     */
-    public void testGet2DigitYearStart() {
-        SimpleDateFormat sdf = new SimpleDateFormat(md2);
-        sdf.set2DigitYearStart(date);
-        assertEquals(date, sdf.get2DigitYearStart());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.toPattern()'
-     */
-    public void testToPattern() {
-        SimpleDateFormat sdf = new SimpleDateFormat(mdy);
-        assertEquals(mdy, sdf.toPattern());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.toLocalizedPattern()'
-     */
-    public void testToLocalizedPattern() {
-        Locale l = Locale.getDefault();
-        Locale.setDefault(Locale.US);
-        SimpleDateFormat sdf = new SimpleDateFormat(mdy);
-        assertEquals(mdy, sdf.toLocalizedPattern());
-        Locale.setDefault(l);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.applyPattern(String)'
-     */
-    public void testApplyPattern() {
-        SimpleDateFormat sdf = new SimpleDateFormat();
-        sdf.setTimeZone(tzc);
-        sdf.applyPattern(hmzmdy);
-        assertEquals(hmzmdyStr, sdf.format(date));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.applyLocalizedPattern(String)'
-     */
-    public void testApplyLocalizedPattern() {
-        SimpleDateFormat sdf = new SimpleDateFormat();
-        sdf.setTimeZone(tzc);
-        sdf.applyLocalizedPattern(hmzmdy);
-        assertEquals(hmzmdyStr, sdf.format(date));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.getDateFormatSymbols()'
-     */
-    public void testGetDateFormatSymbols() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
-        SimpleDateFormat sdf = new SimpleDateFormat(mdy, dfs);
-        assertEquals(dfs, sdf.getDateFormatSymbols());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.text.SimpleDateFormat.setDateFormatSymbols(DateFormatSymbols)'
-     */
-    public void testSetDateFormatSymbols() {
-        DateFormatSymbols dfs = new DateFormatSymbols(Locale.JAPAN);
-        SimpleDateFormat sdf = new SimpleDateFormat(hmzmdy);
-        sdf.setDateFormatSymbols(dfs);
-        // assumes Japanese symbols do not have gregorian month names
-        assertEquals(-1, sdf.format(date).indexOf("Jan"));
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/TimeZoneTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/TimeZoneTest.java
deleted file mode 100644
index 46afd71..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/TimeZoneTest.java
+++ /dev/null
@@ -1,237 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2006-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.tests;
-
-import java.util.Date;
-import java.util.Locale;
-
-import com.ibm.icu.util.Calendar;
-import com.ibm.icu.util.TimeZone;
-import com.ibm.icu.util.ULocale;
-
-public class TimeZoneTest extends ICUTestCase {
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.hashCode()'
-     */
-    public void testHashCode() {
-        TimeZone tz1 = TimeZone.getTimeZone("PST");
-        TimeZone tz2 = TimeZone.getTimeZone("PST");
-        TimeZone tzn = TimeZone.getTimeZone("CST");
-        testEHCS(tz1, tz2, tzn);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.TimeZone(TimeZone)'
-     */
-    public void testTimeZone() {
-        // implicitly tested everywhere
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.getOffset(int, int, int, int, int, int)'
-     */
-    public void testGetOffset() {
-        TimeZone tz = TimeZone.getTimeZone("PST");
-        int offset = tz.getOffset(1, 2004, 0, 01, 1, 0);
-        assertEquals(-28800000, offset);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.setRawOffset(int)'
-     */
-    public void testSetRawOffset() {
-        TimeZone tz = TimeZone.getTimeZone("PST");
-        int value = tz.getRawOffset();
-        int value1 = value + 100000;
-        tz.setRawOffset(value1);
-        int result = tz.getRawOffset();
-        assertNotEqual(value, result);
-        assertEquals(value1, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.getRawOffset()'
-     */
-    public void testGetRawOffset() {
-        TimeZone tz = TimeZone.getTimeZone("PST");
-        int offset = tz.getRawOffset();
-        assertEquals(-28800000, offset);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.getID()'
-     */
-    public void testGetID() {
-        TimeZone tz = TimeZone.getTimeZone("PST");
-        assertEquals("PST", tz.getID());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.setID(String)'
-     */
-    public void testSetID() {
-        TimeZone tz = TimeZone.getTimeZone("PST");
-        String value1 = tz.getID();
-        String value2 = value1 + "!";
-        tz.setID(value2);
-        String result = tz.getID();
-        assertNotEqual(value1, result);
-        assertEquals(value2, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName()'
-     */
-    public void testGetDisplayName() {
-        TimeZone tz = TimeZone.getTimeZone("PST");
-        assertEquals("Pacific Standard Time", tz.getDisplayName());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName(Locale)'
-     */
-    public void testGetDisplayNameLocale() {
-        TimeZone tz = TimeZone.getTimeZone("PST");
-        assertEquals("Pacific Standard Time", tz.getDisplayName(Locale.US));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName(ULocale)'
-     */
-    public void testGetDisplayNameULocale() {
-        TimeZone tz = TimeZone.getTimeZone("PST");
-        assertEquals("Pacific Standard Time", tz.getDisplayName(ULocale.US));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName(boolean, int)'
-     */
-    public void testGetDisplayNameBooleanInt() {
-        TimeZone tz = TimeZone.getTimeZone("PST");
-        assertEquals("PDT", tz.getDisplayName(true, TimeZone.SHORT));
-        assertEquals("Pacific Daylight Time", tz.getDisplayName(true, TimeZone.LONG));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName(boolean, int, Locale)'
-     */
-    public void testGetDisplayNameBooleanIntLocale() {
-        TimeZone tz = TimeZone.getTimeZone("PST");
-        assertEquals("PDT", tz.getDisplayName(true, TimeZone.SHORT, Locale.US));
-        assertEquals("Pacific Daylight Time", tz.getDisplayName(true, TimeZone.LONG, Locale.US));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.getDisplayName(boolean, int, ULocale)'
-     */
-    public void testGetDisplayNameBooleanIntULocale() {
-        TimeZone tz = TimeZone.getTimeZone("PST");
-        assertEquals("PDT", tz.getDisplayName(true, TimeZone.SHORT, ULocale.US));
-        assertEquals("Pacific Daylight Time", tz.getDisplayName(true, TimeZone.LONG, ULocale.US));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.getDSTSavings()'
-     */
-    public void testGetDSTSavings() {
-        TimeZone tz = TimeZone.getTimeZone("PST");
-        assertEquals(3600000, tz.getDSTSavings());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.useDaylightTime()'
-     */
-    public void testUseDaylightTime() {
-        TimeZone tz = TimeZone.getTimeZone("PST");
-        assertTrue(tz.useDaylightTime());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.inDaylightTime(Date)'
-     */
-    public void testInDaylightTime() {
-        TimeZone tz = TimeZone.getTimeZone("PST");
-        Calendar cal = Calendar.getInstance();
-        cal.set(2005, 0, 17);
-        Date date = cal.getTime();
-        assertFalse(tz.inDaylightTime(date));
-        cal.set(2005, 6, 17);
-        date = cal.getTime();
-        assertTrue(tz.inDaylightTime(date));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.getTimeZone(String)'
-     */
-    public void testGetTimeZone() {
-        // implicitly tested everywhere
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.getAvailableIDs(int)'
-     */
-    public void testGetAvailableIDsInt() {
-        String[] ids = TimeZone.getAvailableIDs(-28800000);
-        assertNotNull(ids);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.getAvailableIDs()'
-     */
-    public void testGetAvailableIDs() {
-        String[] ids = TimeZone.getAvailableIDs();
-        assertNotNull(ids);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.getDefault()'
-     */
-    public void testGetDefault() {
-        TimeZone tz = TimeZone.getDefault();
-        assertNotNull(tz);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.setDefault(TimeZone)'
-     */
-    public void testSetDefault() {
-        TimeZone tz1 = TimeZone.getDefault();
-        String newCode = "PDT".equals(tz1.getID()) ? "CST" : "PDT";
-        TimeZone tz2 = TimeZone.getTimeZone(newCode);
-        TimeZone.setDefault(tz2);
-        TimeZone result = TimeZone.getDefault();
-        assertNotEqual(tz1, result);
-        assertEquals(tz2, result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.hasSameRules(TimeZone)'
-     */
-    public void testHasSameRules() {
-        TimeZone tz1 = TimeZone.getTimeZone("PST");
-        TimeZone tz2 = TimeZone.getTimeZone("America/Los_Angeles");
-        assertTrue(tz1.hasSameRules(tz2));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.clone()'
-     */
-    public void testClone() {
-        // tested by testHashCode
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.util.TimeZone.equals(Object)'
-     */
-    public void testEqualsObject() {
-        // tested by testHashCode
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ULocaleTest.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ULocaleTest.java
deleted file mode 100644
index 21d95d4..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base.tests/src/com/ibm/icu/tests/ULocaleTest.java
+++ /dev/null
@@ -1,849 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2006-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.tests;
-
-import java.util.Iterator;
-import java.util.Locale;
-
-import com.ibm.icu.util.ULocale;
-import com.ibm.icu.util.ULocale.Category;
-
-public class ULocaleTest extends ICUTestCase {
-    private String sampleName;
-    private String longULocaleName;
-    private String longULocaleBasename;
-    private String nonNormalizedName;
-    private ULocale longULocale;
-    private Locale sampleLocale;
-        
-    /**
-     * @Override
-     */
-    protected void setUp() throws Exception {
-        super.setUp();
-                
-        sampleName = "ll_CC_VVVV";
-        longULocaleName = "ll_Ssss_CC_VVVV@collation=phonebook;key=value";
-        longULocaleBasename = longULocaleName.substring(0, longULocaleName.indexOf('@'));
-        nonNormalizedName = "LL_ssss_cc_VVVV@ Key = value ; Collation = phonebook ; ";
-        longULocale = new ULocale(longULocaleName);
-        sampleLocale = new ULocale(sampleName).toLocale();
-    }
-        
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.hashCode()'
-     */
-    public void testHashCode() {
-        ULocale obj = ULocale.GERMANY;
-        ULocale eq = new ULocale("de_DE");
-        ULocale neq = new ULocale("de_DE_FRENCH");
-                
-        ICUTestCase.testEHCS(obj, eq, neq);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.forLocale(Locale)'
-     */
-    public void testForLocale() {
-        assertEquals(ULocale.GERMANY, ULocale.forLocale(Locale.GERMANY));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.ULocale(String)'
-     */
-    public void testULocaleString() {
-        assertEquals(ULocale.GERMAN, new ULocale("de"));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.ULocale(String, String)'
-     */
-    public void testULocaleStringString() {
-        assertEquals(ULocale.GERMANY, new ULocale("de", "DE"));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.ULocale(String, String, String)'
-     */
-    public void testULocaleStringStringString() {
-        assertEquals(sampleLocale, new ULocale("ll", "cc", "VVVV").toLocale());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.createCanonical(String)'
-     */
-    public void testCreateCanonical() {
-        ULocale result = ULocale.createCanonical("de__PHONEBOOK");
-        assertEquals(new ULocale("de@collation=phonebook"), result);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.toLocale()'
-     */
-    public void testToLocale() {
-        assertEquals(sampleLocale, new ULocale("ll", "cc", "VVVV").toLocale());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDefault()'
-     */
-    public void testGetDefault() {
-        assertEquals(Locale.getDefault(), ULocale.getDefault().toLocale());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.setDefault(ULocale)'
-     */
-    public void testSetDefault() {
-        Locale oldLocale = Locale.getDefault();
-        ULocale oldULocale = ULocale.getDefault();
-        try {
-            ULocale.setDefault(longULocale);
-            ICUTestCase.assertNotEqual(Locale.getDefault(), oldLocale);
-            ICUTestCase.assertNotEqual(ULocale.getDefault(), oldULocale);
-            assertEquals(longULocale, ULocale.getDefault());
-            assertEquals(sampleLocale, Locale.getDefault());
-        }
-        finally {
-            ULocale.setDefault(oldULocale);
-            Locale.setDefault(oldLocale); // in case of some error
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.clone()'
-     */
-    public void testClone() {
-        // see testHashcode
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.equals(Object)'
-     */
-    public void testEqualsObject() {
-        // see testHashcode
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getAvailableLocales()'
-     */
-    public void testGetAvailableLocales() {
-        ULocale[] ulocales = ULocale.getAvailableLocales();
-        if (ICUTestCase.testingWrapper) {
-            Locale[] locales = Locale.getAvailableLocales();
-            for (int i = 0; i < ulocales.length; ++i) {
-                assertEquals(ulocales[i].toLocale(), locales[i]);
-            }
-        }
-        // else nothing to test except that the function returned.
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getISOCountries()'
-     */
-    public void testGetISOCountries() {
-        String[] ucountries = ULocale.getISOCountries();
-        assertNotNull(ucountries);
-        if (ICUTestCase.testingWrapper) {
-            // keep our own data for now
-            // our data doesn't match java's so this test would fail
-            // TODO: enable if we decide to use java's data
-            // String[] countries = Locale.getISOCountries();
-            // TestBoilerplate.assertArraysEqual(ucountries, countries);
-        }
-        // else nothing to test except that the function returned.
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getISOLanguages()'
-     */
-    public void testGetISOLanguages() {
-        String[] ulanguages = ULocale.getISOLanguages();
-        assertNotNull(ulanguages);
-        if (ICUTestCase.testingWrapper) {
-            // keep our own data for now
-            // our data doesn't match java's so this test would fail
-            // TODO: enable if we decide to use java's data
-            // String[] languages = Locale.getISOLanguages();
-            // TestBoilerplate.assertArraysEqual(ulanguages, languages);
-        }
-        // else nothing to test except that the function returned.
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getLanguage()'
-     */
-    public void testGetLanguage() {
-        assertEquals("ll", longULocale.getLanguage());
-        assertEquals("ll", longULocale.toLocale().getLanguage());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getLanguage(String)'
-     */
-    public void testGetLanguageString() {
-        assertEquals("ll", ULocale.getLanguage(longULocale.getName()));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getScript()'
-     */
-    public void testGetScript() {
-        assertEquals("Ssss", longULocale.getScript());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getScript(String)'
-     */
-    public void testGetScriptString() {
-        assertEquals("Ssss", ULocale.getScript(longULocale.getName()));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getCountry()'
-     */
-    public void testGetCountry() {
-        assertEquals("CC", longULocale.getCountry());
-        assertEquals("CC", longULocale.toLocale().getCountry());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getCountry(String)'
-     */
-    public void testGetCountryString() {
-        assertEquals("CC", ULocale.getCountry(longULocale.getName()));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getVariant()'
-     */
-    public void testGetVariant() {
-        assertEquals("VVVV", longULocale.getVariant());
-        assertEquals("VVVV", longULocale.toLocale().getVariant());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getVariant(String)'
-     */
-    public void testGetVariantString() {
-        assertEquals("VVVV", ULocale.getVariant(longULocale.getName()));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getFallback(String)'
-     */
-    public void testGetFallbackString() {
-        assertEquals(ULocale.GERMAN, ULocale.getFallback(ULocale.GERMANY.getName()));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getFallback()'
-     */
-    public void testGetFallback() {
-        assertEquals(ULocale.GERMAN, ULocale.GERMANY.getFallback());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getBaseName()'
-     */
-    public void testGetBaseName() {
-        assertEquals(longULocaleBasename, longULocale.getBaseName());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getBaseName(String)'
-     */
-    public void testGetBaseNameString() {
-        assertEquals(longULocaleBasename, longULocale.getBaseName());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getName()'
-     */
-    public void testGetName() {
-        assertEquals(longULocaleName, longULocale.getName());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getName(String)'
-     */
-    public void testGetNameString() {
-        assertEquals(longULocaleName, ULocale.getName(nonNormalizedName));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.toString()'
-     */
-    public void testToString() {
-        assertEquals(longULocaleName, longULocale.toString());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getKeywords()'
-     */
-    public void testGetKeywords() {
-        Iterator<String> iter = longULocale.getKeywords();
-        assertEquals(iter.next(), "collation");
-        assertEquals(iter.next(), "key");
-        assertFalse(iter.hasNext());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getKeywords(String)'
-     */
-    public void testGetKeywordsString() {
-        Iterator<String> iter = ULocale.getKeywords(nonNormalizedName);
-        assertEquals(iter.next(), "collation");
-        assertEquals(iter.next(), "key");
-        assertFalse(iter.hasNext());
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getKeywordValue(String)'
-     */
-    public void testGetKeywordValueString() {
-        assertEquals("value", longULocale.getKeywordValue("key"));
-        assertEquals("phonebook", longULocale.getKeywordValue("collation"));
-        assertNull(longULocale.getKeywordValue("zzyzx"));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getKeywordValue(String, String)'
-     */
-    public void testGetKeywordValueStringString() {
-        assertEquals("value", ULocale.getKeywordValue(longULocaleName, "key"));
-        assertEquals("phonebook", ULocale.getKeywordValue(longULocaleName, "collation"));
-        assertNull(ULocale.getKeywordValue(longULocaleName, "zzyzx"));
-
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.canonicalize(String)'
-     */
-    public void testCanonicalize() {
-        assertEquals("de@collation=phonebook", ULocale.canonicalize("de__PHONEBOOK"));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.setKeywordValue(String, String)'
-     */
-    public void testSetKeywordValueStringString() {
-        ULocale munged = longULocale.setKeywordValue("key", "C#");
-        assertEquals("C#", munged.getKeywordValue("key"));
-        munged = munged.setKeywordValue("zzyzx", "grue");
-        assertEquals("grue", munged.getKeywordValue("zzyzx"));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.setKeywordValue(String, String, String)'
-     */
-    public void testSetKeywordValueStringStringString() {
-        String munged = ULocale.setKeywordValue(longULocaleName, "key", "C#");
-        assertEquals("C#", ULocale.getKeywordValue(munged, "key"));
-        munged = ULocale.setKeywordValue(munged, "zzyzx", "grue");
-        assertEquals("grue", ULocale.getKeywordValue(munged, "zzyzx"));
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getISO3Language()'
-     */
-    public void testGetISO3Language() {
-        String il = ULocale.GERMANY.getISO3Language();
-        String jl = Locale.GERMANY.getISO3Language();
-        assertEquals(il, jl);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getISO3Language(String)'
-     */
-    public void testGetISO3LanguageString() {
-        String il = ULocale.getISO3Language(ULocale.GERMANY.getName());
-        String jl = Locale.GERMANY.getISO3Language();
-        assertEquals(il, jl);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getISO3Country()'
-     */
-    public void testGetISO3Country() {
-        String ic = ULocale.GERMANY.getISO3Country();
-        String jc = Locale.GERMANY.getISO3Country();
-        assertEquals(ic, jc);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getISO3Country(String)'
-     */
-    public void testGetISO3CountryString() {
-        String ic = ULocale.getISO3Country(ULocale.GERMANY.getName());
-        String jc = Locale.GERMANY.getISO3Country();
-        assertEquals(ic, jc);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayLanguage()'
-     */
-    public void testGetDisplayLanguage() {
-        String idl = ULocale.GERMANY.getDisplayLanguage();
-        String jdl = Locale.GERMANY.getDisplayLanguage();
-        assertEquals(idl, jdl);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayLanguage(ULocale)'
-     */
-    public void testGetDisplayLanguageULocale() {
-        String idl = ULocale.GERMANY.getDisplayLanguage(ULocale.GERMANY);
-        String jdl = Locale.GERMANY.getDisplayLanguage(Locale.GERMANY);
-        assertEquals(idl, jdl);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayLanguage(String, String)'
-     */
-    public void testGetDisplayLanguageStringString() {
-        String idl = ULocale.getDisplayLanguage(ULocale.GERMANY.getName(), "de_DE");
-        String jdl = Locale.GERMANY.getDisplayLanguage(Locale.GERMANY);
-        assertEquals(idl, jdl);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayLanguage(String, ULocale)'
-     */
-    public void testGetDisplayLanguageStringULocale() {
-        String idl = ULocale.getDisplayLanguage(ULocale.GERMANY.getName(), ULocale.GERMANY);
-        String jdl = Locale.GERMANY.getDisplayLanguage(Locale.GERMANY);
-        assertEquals(idl, jdl);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayScript()'
-     */
-    public void testGetDisplayScript() {
-        String is = ULocale.TRADITIONAL_CHINESE.getDisplayScript();
-        if (ICUTestCase.testingWrapper) {
-            assertEquals("Hant", is);
-        } else {
-            assertEquals("Traditional Chinese", is);
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayScript(ULocale)'
-     */
-    public void testGetDisplayScriptULocale() {
-        String is = ULocale.TRADITIONAL_CHINESE.getDisplayScript(ULocale.GERMANY);
-        if (ICUTestCase.testingWrapper) {
-            assertEquals("Hant", is);
-        } else {
-            // TODO: look up expected value
-            assertEquals("Hant", is);
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayScript(String, String)'
-     */
-    public void testGetDisplayScriptStringString() {
-        String is = ULocale.getDisplayScript("zh_Hant", "de_DE");
-        if (ICUTestCase.testingWrapper) {
-            assertEquals("Hant", is);
-        } else {
-            // TODO: look up expected value
-            assertEquals("Hant", is);
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayScript(String, ULocale)'
-     */
-    public void testGetDisplayScriptStringULocale() {
-        String is = ULocale.getDisplayScript("zh_Hant", ULocale.GERMANY);
-        if (ICUTestCase.testingWrapper) {
-            assertEquals("Hant", is);
-        } else {
-            // TODO: look up expected value
-            assertEquals("Hant", is);
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayCountry()'
-     */
-    public void testGetDisplayCountry() {
-        String idc = ULocale.GERMANY.getDisplayCountry();
-        String jdc = Locale.GERMANY.getDisplayCountry();
-        assertEquals(idc, jdc);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayCountry(ULocale)'
-     */
-    public void testGetDisplayCountryULocale() {
-        String idc = ULocale.GERMANY.getDisplayCountry(ULocale.GERMANY);
-        String jdc = Locale.GERMANY.getDisplayCountry(Locale.GERMANY);
-        assertEquals(idc, jdc);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayCountry(String, String)'
-     */
-    public void testGetDisplayCountryStringString() {
-        String idc = ULocale.getDisplayCountry("de_DE", "de_DE");
-        String jdc = Locale.GERMANY.getDisplayCountry(Locale.GERMANY);
-        assertEquals(idc, jdc);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayCountry(String, ULocale)'
-     */
-    public void testGetDisplayCountryStringULocale() {
-        String idc = ULocale.getDisplayCountry("de_DE", ULocale.GERMANY);
-        String jdc = Locale.GERMANY.getDisplayCountry(Locale.GERMANY);
-        assertEquals(idc, jdc);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayVariant()'
-     */
-    public void testGetDisplayVariant() {
-        String idv = new ULocale("de_DE_PHONEBOOK").getDisplayVariant();
-        String jdv = new Locale("de", "DE", "PHONEBOOK").getDisplayVariant();
-        assertEquals(jdv, idv);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayVariant(ULocale)'
-     */
-    public void testGetDisplayVariantULocale() {
-        String idv = new ULocale("de_DE_PHONEBOOK").getDisplayVariant(ULocale.GERMANY);
-        String jdv = new Locale("de", "DE", "PHONEBOOK").getDisplayVariant(Locale.GERMANY);
-        assertEquals(jdv, idv);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayVariant(String, String)'
-     */
-    public void testGetDisplayVariantStringString() {
-        String idv = ULocale.getDisplayVariant("de_DE_PHONEBOOK", "de_DE");
-        String jdv = new Locale("de", "DE", "PHONEBOOK").getDisplayVariant(Locale.GERMANY);
-        assertEquals(jdv, idv);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayVariant(String, ULocale)'
-     */
-    public void testGetDisplayVariantStringULocale() {
-        String idv = ULocale.getDisplayVariant("de_DE_PHONEBOOK", ULocale.GERMANY);
-        String jdv = new Locale("de", "DE", "PHONEBOOK").getDisplayVariant(Locale.GERMANY);
-        assertEquals(jdv, idv);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeyword(String)'
-     */
-    public void testGetDisplayKeywordString() {
-        String idk = ULocale.getDisplayKeyword("collation");
-        assertEquals("collation", idk);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeyword(String, String)'
-     */
-    public void testGetDisplayKeywordStringString() {
-        String idk = ULocale.getDisplayKeyword("collation", "de_DE");
-        if (ICUTestCase.testingWrapper) {
-            assertEquals("collation", idk);
-        } else {
-            // TODO: find real value
-            assertEquals("collation", idk);
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeyword(String, ULocale)'
-     */
-    public void testGetDisplayKeywordStringULocale() {
-        String idk = ULocale.getDisplayKeyword("collation", ULocale.GERMANY);
-        if (ICUTestCase.testingWrapper) {
-            assertEquals("collation", idk);
-        } else {
-            // TODO: find real value
-            assertEquals("collation", idk);
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeywordValue(String)'
-     */
-    public void testGetDisplayKeywordValueString() {
-        ULocale ul = new ULocale("de_DE@collation=phonebook");
-        String idk = ul.getDisplayKeywordValue("collation");
-        if (ICUTestCase.testingWrapper) {
-            assertEquals("phonebook", idk);
-        } else {
-            // TODO: find real value
-            assertEquals("phonebook", idk);
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeywordValue(String, ULocale)'
-     */
-    public void testGetDisplayKeywordValueStringULocale() {
-        ULocale ul = new ULocale("de_DE@collation=phonebook");
-        String idk = ul.getDisplayKeywordValue("collation", ULocale.GERMANY);
-        if (ICUTestCase.testingWrapper) {
-            assertEquals("phonebook", idk);
-        } else {
-            // TODO: find real value
-            assertEquals("phonebook", idk);
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeywordValue(String, String, String)'
-     */
-    public void testGetDisplayKeywordValueStringStringString() {
-        String idk = ULocale.getDisplayKeywordValue("de_DE@collation=phonebook", "collation", "de_DE");
-        if (ICUTestCase.testingWrapper) {
-            assertEquals("phonebook", idk);
-        } else {
-            // TODO: find real value
-            assertEquals("phonebook", idk);
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayKeywordValue(String, String, ULocale)'
-     */
-    public void testGetDisplayKeywordValueStringStringULocale() {
-        String idk = ULocale.getDisplayKeywordValue("de_DE@collation=phonebook", "collation", ULocale.GERMANY);
-        if (ICUTestCase.testingWrapper) {
-            assertEquals("phonebook", idk);
-        } else {
-            // TODO: find real value
-            assertEquals("phonebook", idk);
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayName()'
-     */
-    public void testGetDisplayName() {
-        String idn = ULocale.GERMANY.getDisplayName();
-        String jdn = Locale.GERMANY.getDisplayName();
-        assertEquals(idn, jdn);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayName(ULocale)'
-     */
-    public void testGetDisplayNameULocale() {
-        String idn = ULocale.GERMANY.getDisplayName(ULocale.GERMANY);
-        String jdn = Locale.GERMANY.getDisplayName(Locale.GERMANY);
-        assertEquals(idn, jdn);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayName(String, String)'
-     */
-    public void testGetDisplayNameStringString() {
-        String idn = ULocale.getDisplayName("de_DE", "de_DE");
-        String jdn = Locale.GERMANY.getDisplayName(Locale.GERMANY);
-        assertEquals(idn, jdn);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDisplayName(String, ULocale)'
-     */
-    public void testGetDisplayNameStringULocale() {
-        String idn = ULocale.getDisplayName("de_DE", ULocale.GERMANY);
-        String jdn = Locale.GERMANY.getDisplayName(Locale.GERMANY);
-        assertEquals(idn, jdn);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.acceptLanguage(String, ULocale[], boolean[])'
-     */
-    public void testAcceptLanguageStringULocaleArrayBooleanArray() {
-        boolean[] fallback = new boolean[1];
-        ULocale[] locales = { 
-            new ULocale("en_CA"), 
-            new ULocale("es_US"), 
-        };
-        ULocale result = ULocale.acceptLanguage("en-US, en-GB, en-CA, es-US", locales, fallback);
-        assertEquals(new ULocale("en_CA"), result);
-        assertFalse(fallback[0]);
-        result = ULocale.acceptLanguage("en-US, en-GB, es-US-NEWMEXICO", locales, fallback);
-        assertEquals(new ULocale("es_US"), result);
-        assertTrue(fallback[0]);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.acceptLanguage(ULocale[], ULocale[], boolean[])'
-     */
-    public void testAcceptLanguageULocaleArrayULocaleArrayBooleanArray() {
-        boolean[] fallback = new boolean[1];
-        ULocale[] locales = { 
-            new ULocale("en_CA"), 
-            new ULocale("es_US"), 
-        };
-        ULocale[] accept_locales = {
-            new ULocale("en_US"),
-            new ULocale("en_GB"),
-            new ULocale("en_CA"),
-            new ULocale("es_US"),
-        };
-        ULocale[] accept_locales2 = {
-            new ULocale("en_US"),
-            new ULocale("en_GB"),
-            new ULocale("es_US_NEWMEXICO"),
-        };
-        ULocale result = ULocale.acceptLanguage(accept_locales, locales, fallback);
-        assertEquals(new ULocale("en_CA"), result);
-        assertFalse(fallback[0]);
-        result = ULocale.acceptLanguage(accept_locales2, locales, fallback);
-        assertEquals(new ULocale("es_US"), result);
-        assertTrue(fallback[0]);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.acceptLanguage(String, boolean[])'
-     */
-    public void testAcceptLanguageStringBooleanArray() {
-        boolean[] fallback = new boolean[1];
-        ULocale result = ULocale.acceptLanguage("en-CA, en-GB, es-US", fallback);
-        assertEquals(new ULocale("en_CA"), result);
-        assertFalse(fallback[0]);
-        result = ULocale.acceptLanguage("es-US-NEWMEXICO", fallback);
-        assertNotNull(result); // actual result depends on jdk
-        assertTrue(fallback[0]);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.acceptLanguage(ULocale[], boolean[])'
-     */
-    public void testAcceptLanguageULocaleArrayBooleanArray() {
-        boolean[] fallback = new boolean[1];
-        ULocale[] accept_locales = {
-            new ULocale("en_CA"),
-            new ULocale("en_GB"),
-            new ULocale("es_US"),
-        };
-        ULocale[] accept_locales2 = {
-            new ULocale("es_US_NEWMEXICO"),
-        };
-        ULocale result = ULocale.acceptLanguage(accept_locales, fallback);
-        assertEquals(new ULocale("en_CA"), result);
-        assertFalse(fallback[0]);
-        result = ULocale.acceptLanguage(accept_locales2, fallback);
-        assertNotNull(result); // actual result depends on jdk
-        assertTrue(fallback[0]);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.toLanguageTag()'
-     */
-    public void testToLanguageTag() {
-        ULocale[] test_ulocales = {
-            new ULocale("en_US"),
-            new ULocale(""),
-            new ULocale("de_DE@collation=phonebook"),
-            new ULocale("en_Latn_US_POSIX"),
-            new ULocale("th_TH@numbers=thai;calendar=buddhist"),
-            new ULocale("und_CN@timezone=PRC"),
-            new ULocale("iw_IL"),
-        };
-
-        String[] expected = {
-            "en-US",
-            "und",
-            "de-DE-u-co-phonebk",
-            "en-Latn-US-u-va-posix",
-            "th-TH-u-ca-buddhist-nu-thai",
-            "und-CN-u-tz-cnsha",
-            "he-IL",
-        };
-
-        for (int i = 0; i < test_ulocales.length; i++) {
-            String result = test_ulocales[i].toLanguageTag();
-            assertEquals(expected[i], result);
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.forLanguageTag()'
-     */
-    public void testForLanguageTag() {
-        String[] test_tags = {
-            "en-us",
-            "Und-Us",
-            "ja-jp-u-ca-japanese",
-            "fr-FR-u-tz-frpar-ca-gregory",
-        };
-
-        ULocale[] expected = {
-            new ULocale("en_US"),
-            new ULocale("und_US"),
-            new ULocale("ja_JP@calendar=japanese"),
-            new ULocale("fr_FR@calendar=gregorian;timezone=Europe/Paris"),
-        };
-
-        for (int i = 0; i < test_tags.length; i++) {
-            ULocale result = ULocale.forLanguageTag(test_tags[i]);
-            assertEquals(expected[i], result);
-        }
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.getDefault(Category)'
-     */
-    public void testGetDefaultCategory() {
-        ULocale dispLoc = ULocale.getDefault(Category.DISPLAY);
-        assertNotNull(dispLoc);
-        ULocale formLoc = ULocale.getDefault(Category.FORMAT);
-        assertNotNull(formLoc);
-    }
-
-    /*
-     * Test method for 'com.ibm.icu.x.util.ULocale.setDefault(Category, ULocale)'
-     */
-    public void testSetDefaultCategoryULocale() {
-        ULocale orgDefault = ULocale.getDefault();
-        ULocale orgDisplay = ULocale.getDefault(Category.DISPLAY);
-        ULocale orgFormat = ULocale.getDefault(Category.FORMAT);
-
-        ULocale jaUS = new ULocale("ja_US");
-        ULocale.setDefault(jaUS);
-
-        // setDefault(ULocale) updates category defaults
-        assertEquals(ULocale.getDefault(), jaUS);
-        assertEquals(ULocale.getDefault(Category.DISPLAY), jaUS);
-        assertEquals(ULocale.getDefault(Category.FORMAT), jaUS);
-
-        ULocale frDE = new ULocale("fr_DE");
-        ULocale.setDefault(Category.DISPLAY, frDE);
-
-        // setDefault(Category, ULocale) only updates the category default
-        assertEquals(ULocale.getDefault(), jaUS);
-        assertEquals(ULocale.getDefault(Category.DISPLAY), frDE);
-        assertEquals(ULocale.getDefault(Category.FORMAT), jaUS);
-
-        // restore the original
-        ULocale.setDefault(orgDefault);
-        ULocale.setDefault(Category.DISPLAY, orgDisplay);
-        ULocale.setDefault(Category.FORMAT, orgFormat);
-
-        assertEquals(ULocale.getDefault(), orgDefault);
-        assertEquals(ULocale.getDefault(Category.DISPLAY), orgDisplay);
-        assertEquals(ULocale.getDefault(Category.FORMAT), orgFormat);
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.classpath b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.classpath
deleted file mode 100644
index 3bc2475..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.project b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.project
deleted file mode 100644
index 718a3c0..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.project
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>com.ibm.icu.base</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.ManifestBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.SchemaBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-		<nature>org.eclipse.pde.PluginNature</nature>
-	</natures>
-</projectDescription>
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.settings/org.eclipse.core.resources.prefs b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c0..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/<project>=UTF-8
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.settings/org.eclipse.jdt.core.prefs b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index a8076c5..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,76 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=ignore
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=warning
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.7
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.settings/org.eclipse.jdt.ui.prefs b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.settings/org.eclipse.jdt.ui.prefs
deleted file mode 100644
index 5693f2f..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/.settings/org.eclipse.jdt.ui.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Thu Dec 14 11:50:17 EST 2006
-eclipse.preferences.version=1
-internal.default.compliance=default
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/META-INF/MANIFEST.MF b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/META-INF/MANIFEST.MF
deleted file mode 100644
index 4450dcd..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,15 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: %pluginName
-Bundle-SymbolicName: com.ibm.icu.base; singleton:=true
-Bundle-Version: @BUILD_VERSION@
-Bundle-Vendor: %providerName
-Bundle-Localization: plugin
-Bundle-Copyright: @COPYRIGHT@
-Export-Package: com.ibm.icu.text;base=true;version="@IMPL_VERSION@",
- com.ibm.icu.util;base=true;version="@IMPL_VERSION@",
- com.ibm.icu.math;base=true;version="@IMPL_VERSION@",
- com.ibm.icu.impl;x-internal:=true,
- com.ibm.icu.impl.locale;x-internal:=true
-Eclipse-LazyStart: true
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/build.properties b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/build.properties
deleted file mode 100644
index 1e07dde..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/build.properties
+++ /dev/null
@@ -1,19 +0,0 @@
-###############################################################################
-# Copyright (c) 2011 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     IBM Corporation - initial API and implementation
-###############################################################################
-source.. = src/
-output.. = bin/
-src.includes = about.html,\
-               about_files/
-bin.includes = .,\
-               about.html,\
-               about_files/,\
-               plugin.properties,\
-               META-INF/
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/plugin.properties b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/plugin.properties
deleted file mode 100644
index 4da4d9c..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/plugin.properties
+++ /dev/null
@@ -1,12 +0,0 @@
-###############################################################################
-# Copyright (c) 2011 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials 
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     IBM Corporation - initial API and implementation
-###############################################################################
-pluginName = International Components for Unicode for Java (ICU4J) Replacement plug-in
-providerName = IBM Corporation
\ No newline at end of file
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/ICUCache.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/ICUCache.java
deleted file mode 100644
index 2eab100..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/ICUCache.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- ***************************************************************************
- * Copyright (c) 2007-2011 International Business Machines Corporation and *
- * others.  All rights reserved.                                           *
- ***************************************************************************
-*/
-
-package com.ibm.icu.impl;
-
-public interface ICUCache<K, V> {
-    // Type of reference holding the Map instance
-    public static final int SOFT = 0;
-    public static final int WEAK = 1;
-
-    // NULL object, which may be used for a cache key
-    public static final Object NULL = new Object();
-
-    public void clear();
-    public void put(K key, V value);
-    public V get(Object key);
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDParser.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDParser.java
deleted file mode 100644
index 9ee790a..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDParser.java
+++ /dev/null
@@ -1,745 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
-******************************************************************************
-* Copyright (C) 2003-2012, International Business Machines Corporation and   *
-* others. All Rights Reserved.                                               *
-******************************************************************************
-*/
-
-package com.ibm.icu.impl;
-
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.TreeMap;
-
-import com.ibm.icu.impl.locale.AsciiUtil;
-
-/**
- * Utility class to parse and normalize locale ids (including POSIX style)
- */
-public final class LocaleIDParser {
-    
-    /**
-     * Char array representing the locale ID.
-     */
-    private char[] id;
-    
-    /**
-     * Current position in {@link #id} (while parsing).
-     */
-    private int index;
-    
-    /**
-     * Temporary buffer for parsed sections of data.
-     */
-    private StringBuilder buffer;
-    
-    // um, don't handle POSIX ids unless we request it.  why not?  well... because.
-    private boolean canonicalize;
-    private boolean hadCountry;
-
-    // used when canonicalizing
-    Map<String, String> keywords;
-    String baseName;
-
-    /**
-     * Parsing constants.
-     */
-    private static final char KEYWORD_SEPARATOR     = '@';
-    private static final char HYPHEN                = '-';
-    private static final char KEYWORD_ASSIGN        = '=';
-    private static final char COMMA                 = ',';
-    private static final char ITEM_SEPARATOR        = ';';
-    private static final char DOT                   = '.';
-    private static final char UNDERSCORE            = '_';
-
-    public LocaleIDParser(String localeID) {
-        this(localeID, false);
-    }
-
-    public LocaleIDParser(String localeID, boolean canonicalize) {
-        id = localeID.toCharArray();
-        index = 0;
-        buffer = new StringBuilder(id.length + 5);
-        this.canonicalize = canonicalize;
-    }
-
-    private void reset() {
-        index = 0;
-        buffer = new StringBuilder(id.length + 5);
-    }
-
-    // utilities for working on text in the buffer
-    
-    /**
-     * Append c to the buffer.
-     */
-    private void append(char c) {
-        buffer.append(c);
-    }
-    
-    private void addSeparator() {
-        append(UNDERSCORE);
-    }
-
-    /**
-     * Returns the text in the buffer from start to blen as a String.
-     */
-    private String getString(int start) {
-        return buffer.substring(start);
-    }
-
-    /**
-     * Set the length of the buffer to pos, then append the string.
-     */
-    private void set(int pos, String s) {
-        buffer.delete(pos, buffer.length());
-        buffer.insert(pos, s);
-    }
-
-    /**
-     * Append the string to the buffer.
-     */
-    private void append(String s) {
-        buffer.append(s);
-    }
-
-    // utilities for parsing text out of the id
-
-    /**
-     * Character to indicate no more text is available in the id.
-     */
-    private static final char DONE = '\uffff';
-
-    /**
-     * Returns the character at index in the id, and advance index.  The returned character
-     * is DONE if index was at the limit of the buffer.  The index is advanced regardless
-     * so that decrementing the index will always 'unget' the last character returned.
-     */
-    private char next() {
-        if (index == id.length) {
-            index++;
-            return DONE;
-        }
-
-        return id[index++];
-    }
-
-    /**
-     * Advance index until the next terminator or id separator, and leave it there.
-     */
-    private void skipUntilTerminatorOrIDSeparator() {
-        while (!isTerminatorOrIDSeparator(next()));
-        --index;
-    }
-
-    /**
-     * Returns true if the character at index in the id is a terminator.
-     */
-    private boolean atTerminator() {
-        return index >= id.length || isTerminator(id[index]);
-    }
-
-    /**
-     * Returns true if the character is a terminator (keyword separator, dot, or DONE).
-     * Dot is a terminator because of the POSIX form, where dot precedes the codepage.
-     */
-    private boolean isTerminator(char c) {
-        // always terminate at DOT, even if not handling POSIX.  It's an error...
-        return c == KEYWORD_SEPARATOR || c == DONE || c == DOT;
-    }
-
-    /**
-     * Returns true if the character is a terminator or id separator.
-     */
-    private boolean isTerminatorOrIDSeparator(char c) {
-        return c == UNDERSCORE || c == HYPHEN || isTerminator(c);
-    }
-
-    /**
-     * Returns true if the start of the buffer has an experimental or private language
-     * prefix, the pattern '[ixIX][-_].' shows the syntax checked.
-     */
-    private boolean haveExperimentalLanguagePrefix() {
-        if (id.length > 2) {
-            char c = id[1];
-            if (c == HYPHEN || c == UNDERSCORE) {
-                c = id[0];
-                return c == 'x' || c == 'X' || c == 'i' || c == 'I';
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns true if a value separator occurs at or after index.
-     */
-    private boolean haveKeywordAssign() {
-        // assume it is safe to start from index
-        for (int i = index; i < id.length; ++i) {
-            if (id[i] == KEYWORD_ASSIGN) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Advance index past language, and accumulate normalized language code in buffer.
-     * Index must be at 0 when this is called.  Index is left at a terminator or id
-     * separator.  Returns the start of the language code in the buffer.
-     */
-    private int parseLanguage() {
-        int startLength = buffer.length();
-        
-        if (haveExperimentalLanguagePrefix()) {
-            append(AsciiUtil.toLower(id[0]));
-            append(HYPHEN);
-            index = 2;
-        }
-
-        char c;
-        while(!isTerminatorOrIDSeparator(c = next())) {
-            append(AsciiUtil.toLower(c));
-        }
-        --index; // unget
-
-        if (buffer.length() - startLength == 3) {
-            String lang = LocaleIDs.threeToTwoLetterLanguage(getString(0));
-            if (lang != null) {
-                set(0, lang);
-            }
-        }
-
-        return 0;
-    }
-
-    /**
-     * Advance index past language.  Index must be at 0 when this is called.  Index
-     * is left at a terminator or id separator.
-     */
-    private void skipLanguage() {
-        if (haveExperimentalLanguagePrefix()) {
-            index = 2;
-        }
-        skipUntilTerminatorOrIDSeparator();
-    }
-
-    /**
-     * Advance index past script, and accumulate normalized script in buffer.
-     * Index must be immediately after the language.
-     * If the item at this position is not a script (is not four characters
-     * long) leave index and buffer unchanged.  Otherwise index is left at
-     * a terminator or id separator.  Returns the start of the script code
-     * in the buffer (this may be equal to the buffer length, if there is no
-     * script).
-     */
-    private int parseScript() {
-        if (!atTerminator()) {
-            int oldIndex = index; // save original index
-            ++index;
-
-            int oldBlen = buffer.length(); // get before append hyphen, if we truncate everything is undone
-            char c;
-            boolean firstPass = true;
-            while(!isTerminatorOrIDSeparator(c = next()) && AsciiUtil.isAlpha(c)) {
-                if (firstPass) {
-                    addSeparator();
-                    append(AsciiUtil.toUpper(c));
-                    firstPass = false;
-                } else {
-                    append(AsciiUtil.toLower(c));
-                }
-            }
-            --index; // unget
-
-            /* If it's not exactly 4 characters long, then it's not a script. */
-            if (index - oldIndex != 5) { // +1 to account for separator
-                index = oldIndex;
-                buffer.delete(oldBlen, buffer.length());
-            } else {
-                oldBlen++; // index past hyphen, for clients who want to extract just the script
-            }
-
-            return oldBlen;
-        }
-        return buffer.length();
-    }
-
-    /**
-     * Advance index past script.
-     * Index must be immediately after the language and IDSeparator.
-     * If the item at this position is not a script (is not four characters
-     * long) leave index.  Otherwise index is left at a terminator or
-     * id separator.
-     */
-    private void skipScript() {
-        if (!atTerminator()) {
-            int oldIndex = index;
-            ++index;
-            
-            char c;
-            while (!isTerminatorOrIDSeparator(c = next()) && AsciiUtil.isAlpha(c));
-            --index;
-
-            if (index - oldIndex != 5) { // +1 to account for separator
-                index = oldIndex;
-            }
-        }
-    }
-
-    /**
-     * Advance index past country, and accumulate normalized country in buffer.
-     * Index must be immediately after the script (if there is one, else language)
-     * and IDSeparator.  Return the start of the country code in the buffer.
-     */
-    private int parseCountry() {
-        if (!atTerminator()) {
-            int oldIndex = index;
-            ++index;
-
-            int oldBlen = buffer.length();
-            char c;
-            boolean firstPass = true;
-            while (!isTerminatorOrIDSeparator(c = next())) {
-                if (firstPass) { // first, add hyphen
-                    hadCountry = true; // we have a country, let variant parsing know
-                    addSeparator();
-                    ++oldBlen; // increment past hyphen
-                    firstPass = false;
-                }
-                append(AsciiUtil.toUpper(c));
-            }
-            --index; // unget
-
-            int charsAppended = buffer.length() - oldBlen;
-
-            if (charsAppended == 0) {
-                // Do nothing.
-            }
-            else if (charsAppended < 2 || charsAppended > 3) {
-                // It's not a country, so return index and blen to
-                // their previous values.
-                index = oldIndex;
-                --oldBlen;
-                buffer.delete(oldBlen, buffer.length());
-                hadCountry = false;
-            }
-            else if (charsAppended == 3) {
-                String region = LocaleIDs.threeToTwoLetterRegion(getString(oldBlen));
-                if (region != null) {
-                    set(oldBlen, region);
-                }
-            }
-
-            return oldBlen;
-        }
-
-        return buffer.length();
-    }
-
-    /**
-     * Advance index past country.
-     * Index must be immediately after the script (if there is one, else language)
-     * and IDSeparator.
-     */
-    private void skipCountry() {
-        if (!atTerminator()) {
-            if (id[index] == UNDERSCORE || id[index] == HYPHEN) {
-                ++index;
-            }
-            /*
-             * Save the index point after the separator, since the format
-             * requires two separators if the country is not present.
-             */
-            int oldIndex = index;
-
-            skipUntilTerminatorOrIDSeparator();
-            int charsSkipped = index - oldIndex;
-            if (charsSkipped < 2 || charsSkipped > 3) {
-                index = oldIndex;
-            }
-        }
-    }
-
-    /**
-     * Advance index past variant, and accumulate normalized variant in buffer.  This ignores
-     * the codepage information from POSIX ids.  Index must be immediately after the country
-     * or script.  Index is left at the keyword separator or at the end of the text.  Return
-     * the start of the variant code in the buffer.
-     *
-     * In standard form, we can have the following forms:
-     * ll__VVVV
-     * ll_CC_VVVV
-     * ll_Ssss_VVVV
-     * ll_Ssss_CC_VVVV
-     *
-     * This also handles POSIX ids, which can have the following forms (pppp is code page id):
-     * ll_CC.pppp          --> ll_CC
-     * ll_CC.pppp@VVVV     --> ll_CC_VVVV
-     * ll_CC@VVVV          --> ll_CC_VVVV
-     *
-     * We identify this use of '@' in POSIX ids by looking for an '=' following
-     * the '@'.  If there is one, we consider '@' to start a keyword list, instead of
-     * being part of a POSIX id.
-     *
-     * Note:  since it was decided that we want an option to not handle POSIX ids, this
-     * becomes a bit more complex.
-     */
-    private int parseVariant() {
-        int oldBlen = buffer.length();
-
-        boolean start = true;
-        boolean needSeparator = true;
-        boolean skipping = false;
-        char c;
-        boolean firstPass = true;
-        
-        while ((c = next()) != DONE) {
-            if (c == DOT) {
-                start = false;
-                skipping = true;
-            } else if (c == KEYWORD_SEPARATOR) {
-                if (haveKeywordAssign()) {
-                    break;
-                }
-                skipping = false;
-                start = false;
-                needSeparator = true; // add another underscore if we have more text
-            } else if (start) {
-                start = false;
-                if (c != UNDERSCORE && c != HYPHEN) {
-                    index--;
-                }
-            } else if (!skipping) {
-                if (needSeparator) {
-                    needSeparator = false;
-                    if (firstPass && !hadCountry) { // no country, we'll need two
-                        addSeparator();
-                        ++oldBlen; // for sure
-                    }
-                    addSeparator();
-                    if (firstPass) { // only for the first separator
-                        ++oldBlen;
-                        firstPass = false;
-                    }
-                }
-                c = AsciiUtil.toUpper(c);
-                if (c == HYPHEN || c == COMMA) {
-                    c = UNDERSCORE;
-                }
-                append(c);
-            }
-        }
-        --index; // unget
-
-        return oldBlen;
-    }
-
-    // no need for skipvariant, to get the keywords we'll just scan directly for
-    // the keyword separator
-
-    /**
-     * Returns the normalized language id, or the empty string.
-     */
-    public String getLanguage() {
-        reset();
-        return getString(parseLanguage());
-    }
-
-    /**
-     * Returns the normalized script id, or the empty string.
-     */
-    public String getScript() {
-        reset();
-        skipLanguage();
-        return getString(parseScript());
-    }
-
-    /**
-     * return the normalized country id, or the empty string.
-     */
-    public String getCountry() {
-        reset();
-        skipLanguage();
-        skipScript();
-        return getString(parseCountry());
-    }
-
-    /**
-     * Returns the normalized variant id, or the empty string.
-     */
-    public String getVariant() {
-        reset();
-        skipLanguage();
-        skipScript();
-        skipCountry();
-        return getString(parseVariant());
-    }
-
-    /**
-     * Returns the language, script, country, and variant as separate strings.
-     */
-    public String[] getLanguageScriptCountryVariant() {
-        reset();
-        return new String[] {
-                getString(parseLanguage()),
-                getString(parseScript()),
-                getString(parseCountry()),
-                getString(parseVariant())
-        };
-    }
-
-    public void setBaseName(String baseName) {
-        this.baseName = baseName;
-    }
-
-    public void parseBaseName() {
-        if (baseName != null) {
-            set(0, baseName);
-        } else {
-            reset();
-            parseLanguage();
-            parseScript();
-            parseCountry();
-            parseVariant();
-
-            // catch unwanted trailing underscore after country if there was no variant
-            int len = buffer.length();
-            if (len > 0 && buffer.charAt(len - 1) == UNDERSCORE) {
-                buffer.deleteCharAt(len - 1);
-            }
-        }
-    }
-
-    /**
-     * Returns the normalized base form of the locale id.  The base
-     * form does not include keywords.
-     */
-    public String getBaseName() {
-        if (baseName != null) {
-            return baseName;
-        }
-        parseBaseName();
-        return getString(0);
-    }
-
-    /**
-     * Returns the normalized full form of the locale id.  The full
-     * form includes keywords if they are present.
-     */
-    public String getName() {
-        parseBaseName();
-        parseKeywords();
-        return getString(0);
-    }
-
-    // keyword utilities
-
-    /**
-     * If we have keywords, advance index to the start of the keywords and return true,
-     * otherwise return false.
-     */
-    private boolean setToKeywordStart() {
-        for (int i = index; i < id.length; ++i) {
-            if (id[i] == KEYWORD_SEPARATOR) {
-                if (canonicalize) {
-                    for (int j = ++i; j < id.length; ++j) { // increment i past separator for return
-                        if (id[j] == KEYWORD_ASSIGN) {
-                            index = i;
-                            return true;
-                        }
-                    }
-                } else {
-                    if (++i < id.length) {
-                        index = i;
-                        return true;
-                    }
-                }
-                break;
-            }
-        }
-        return false;
-    }
-
-    private static boolean isDoneOrKeywordAssign(char c) {
-        return c == DONE || c == KEYWORD_ASSIGN;
-    }
-
-    private static boolean isDoneOrItemSeparator(char c) {
-        return c == DONE || c == ITEM_SEPARATOR;
-    }
-
-    private String getKeyword() {
-        int start = index;
-        while (!isDoneOrKeywordAssign(next())) {
-        }
-        --index;
-        return AsciiUtil.toLowerString(new String(id, start, index-start).trim());
-    }
-
-    private String getValue() {
-        int start = index;
-        while (!isDoneOrItemSeparator(next())) {
-        }
-        --index;
-        return new String(id, start, index-start).trim(); // leave case alone
-    }
-
-    private Comparator<String> getKeyComparator() {
-        final Comparator<String> comp = new Comparator<String>() {
-            public int compare(String lhs, String rhs) {
-                return lhs.compareTo(rhs);
-            }
-        };
-        return comp;
-    }
-
-    /**
-     * Returns a map of the keywords and values, or null if there are none.
-     */
-    public Map<String, String> getKeywordMap() {
-        if (keywords == null) {
-            TreeMap<String, String> m = null;
-            if (setToKeywordStart()) {
-                // trim spaces and convert to lower case, both keywords and values.
-                do {
-                    String key = getKeyword();
-                    if (key.length() == 0) {
-                        break;
-                    }
-                    char c = next();
-                    if (c != KEYWORD_ASSIGN) {
-                        // throw new IllegalArgumentException("key '" + key + "' missing a value.");
-                        if (c == DONE) {
-                            break;
-                        } else {
-                            continue;
-                        }
-                    }
-                    String value = getValue();
-                    if (value.length() == 0) {
-                        // throw new IllegalArgumentException("key '" + key + "' missing a value.");
-                        continue;
-                    }
-                    if (m == null) {
-                        m = new TreeMap<String, String>(getKeyComparator());
-                    } else if (m.containsKey(key)) {
-                        // throw new IllegalArgumentException("key '" + key + "' already has a value.");
-                        continue;
-                    }
-                    m.put(key, value);
-                } while (next() == ITEM_SEPARATOR);
-            }
-            keywords = m != null ? m : Collections.<String, String>emptyMap();
-        }
-
-        return keywords;
-    }
-
-
-    /**
-     * Parse the keywords and return start of the string in the buffer.
-     */
-    private int parseKeywords() {
-        int oldBlen = buffer.length();
-        Map<String, String> m = getKeywordMap();
-        if (!m.isEmpty()) {
-            boolean first = true;
-            for (Map.Entry<String, String> e : m.entrySet()) {
-                append(first ? KEYWORD_SEPARATOR : ITEM_SEPARATOR);
-                first = false;
-                append(e.getKey());
-                append(KEYWORD_ASSIGN);
-                append(e.getValue());
-            }
-            if (first == false) {
-                ++oldBlen;
-            }
-        }
-        return oldBlen;
-    }
-
-    /**
-     * Returns an iterator over the keywords, or null if we have an empty map.
-     */
-    public Iterator<String> getKeywords() {
-        Map<String, String> m = getKeywordMap();
-        return m.isEmpty() ? null : m.keySet().iterator();
-    }
-
-    /**
-     * Returns the value for the named keyword, or null if the keyword is not
-     * present.
-     */
-    public String getKeywordValue(String keywordName) {
-        Map<String, String> m = getKeywordMap();
-        return m.isEmpty() ? null : m.get(AsciiUtil.toLowerString(keywordName.trim()));
-    }
-
-    /**
-     * Set the keyword value only if it is not already set to something else.
-     */
-    public void defaultKeywordValue(String keywordName, String value) {
-        setKeywordValue(keywordName, value, false);
-    }
-
-    /**
-     * Set the value for the named keyword, or unset it if value is null.  If
-     * keywordName itself is null, unset all keywords.  If keywordName is not null,
-     * value must not be null.
-     */
-    public void setKeywordValue(String keywordName, String value) {
-        setKeywordValue(keywordName, value, true);
-    }
-
-    /**
-     * Set the value for the named keyword, or unset it if value is null.  If
-     * keywordName itself is null, unset all keywords.  If keywordName is not null,
-     * value must not be null.  If reset is true, ignore any previous value for
-     * the keyword, otherwise do not change the keyword (including removal of
-     * one or all keywords).
-     */
-    private void setKeywordValue(String keywordName, String value, boolean reset) {
-        if (keywordName == null) {
-            if (reset) {
-                // force new map, ignore value
-                keywords = Collections.<String, String>emptyMap();
-            }
-        } else {
-            keywordName = AsciiUtil.toLowerString(keywordName.trim());
-            if (keywordName.length() == 0) {
-                throw new IllegalArgumentException("keyword must not be empty");
-            }
-            if (value != null) {
-                value = value.trim();
-                if (value.length() == 0) {
-                    throw new IllegalArgumentException("value must not be empty");
-                }
-            }
-            Map<String, String> m = getKeywordMap();
-            if (m.isEmpty()) { // it is EMPTY_MAP
-                if (value != null) {
-                    // force new map
-                    keywords = new TreeMap<String, String>(getKeyComparator());
-                    keywords.put(keywordName, value.trim());
-                }
-            } else {
-                if (reset || !m.containsKey(keywordName)) {
-                    if (value != null) {
-                        m.put(keywordName, value);
-                    } else {
-                        m.remove(keywordName);
-                        if (m.isEmpty()) {
-                            // force new map
-                            keywords = Collections.<String, String>emptyMap();
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDs.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDs.java
deleted file mode 100644
index dda9d57..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleIDs.java
+++ /dev/null
@@ -1,538 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2009-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.impl;
-
-import java.util.MissingResourceException;
-
-import com.ibm.icu.util.ULocale;
-
-
-/**
- * Utilities for mapping between old and new language, country, and other
- * locale ID related names.
- */
-public class LocaleIDs {
-
-    /**
-     * Returns a list of all 2-letter country codes defined in ISO 3166.
-     * Can be used to create Locales.
-     * @stable ICU 3.0
-     */
-    public static String[] getISOCountries() {
-        initCountryTables();
-        return _countries.clone();
-    }
-
-    /**
-     * Returns a list of all 2-letter language codes defined in ISO 639.
-     * Can be used to create Locales.
-     * [NOTE:  ISO 639 is not a stable standard-- some languages' codes have changed.
-     * The list this function returns includes both the new and the old codes for the
-     * languages whose codes have changed.]
-     * @stable ICU 3.0
-     */
-    public static String[] getISOLanguages() {
-        initLanguageTables();
-        return _languages.clone();
-    }
-
-    /**
-     * Returns a three-letter abbreviation for the provided country.  If the provided
-     * country is empty, returns the empty string.  Otherwise, returns
-     * an uppercase ISO 3166 3-letter country code.
-     * @exception MissingResourceException Throws MissingResourceException if the
-     * three-letter country abbreviation is not available for this locale.
-     * @stable ICU 3.0
-     */
-    public static String getISO3Country(String country){
-        initCountryTables();
-
-        int offset = findIndex(_countries, country);
-        if(offset>=0){
-            return _countries3[offset];
-        }else{
-            offset = findIndex(_obsoleteCountries, country);
-            if(offset>=0){
-                return _obsoleteCountries3[offset];
-            }
-        }
-        return "";
-    }
-    /**
-     * Returns a three-letter abbreviation for the language.  If language is
-     * empty, returns the empty string.  Otherwise, returns
-     * a lowercase ISO 639-2/T language code.
-     * The ISO 639-2 language codes can be found on-line at
-     *   <a href="ftp://dkuug.dk/i18n/iso-639-2.txt"><code>ftp://dkuug.dk/i18n/iso-639-2.txt</code></a>
-     * @exception MissingResourceException Throws MissingResourceException if the
-     * three-letter language abbreviation is not available for this locale.
-     * @stable ICU 3.0
-     */
-    public static String getISO3Language(String language) {
-        initLanguageTables();
-
-        int offset = findIndex(_languages, language);
-        if(offset>=0){
-            return _languages3[offset];
-        } else {
-            offset = findIndex(_obsoleteLanguages, language);
-            if (offset >= 0) {
-                return _obsoleteLanguages3[offset];
-            }
-        }
-        return "";
-    }
-
-    public static String threeToTwoLetterLanguage(String lang) {
-        initLanguageTables();
-
-        /* convert 3 character code to 2 character code if possible *CWB*/
-        int offset = findIndex(_languages3, lang);
-        if (offset >= 0) {
-            return _languages[offset];
-        }
-
-        offset = findIndex(_obsoleteLanguages3, lang);
-        if (offset >= 0) {
-            return _obsoleteLanguages[offset];
-        }
-
-        return null;
-    }
-
-    public static String threeToTwoLetterRegion(String region) {
-        initCountryTables();
-
-        /* convert 3 character code to 2 character code if possible *CWB*/
-        int offset = findIndex(_countries3, region);
-        if (offset >= 0) {
-            return _countries[offset];
-        }
-
-        offset = findIndex(_obsoleteCountries3, region);
-        if (offset >= 0) {
-            return _obsoleteCountries[offset];
-        }
-
-        return null;
-    }
-
-    /**
-     * linear search of the string array. the arrays are unfortunately ordered by the
-     * two-letter target code, not the three-letter search code, which seems backwards.
-     */
-    private static int findIndex(String[] array, String target){
-        for (int i = 0; i < array.length; i++) {
-            if (target.equals(array[i])) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    /**
-     * Tables used in normalizing portions of the id.
-     */
-    /* tables updated per http://lcweb.loc.gov/standards/iso639-2/
-       to include the revisions up to 2001/7/27 *CWB*/
-    /* The 3 character codes are the terminology codes like RFC 3066.
-       This is compatible with prior ICU codes */
-    /* "in" "iw" "ji" "jw" & "sh" have been withdrawn but are still in
-       the table but now at the end of the table because
-       3 character codes are duplicates.  This avoids bad searches
-       going from 3 to 2 character codes.*/
-    /* The range qaa-qtz is reserved for local use. */
-
-    private static String[] _languages;
-    private static String[] _replacementLanguages;
-    private static String[] _obsoleteLanguages;
-    private static String[] _languages3;
-    private static String[] _obsoleteLanguages3;
-
-    // Avoid initializing languages tables unless we have to.
-    private static void initLanguageTables() {
-        if (_languages == null) {
-
-            /* This list MUST be in sorted order, and MUST contain the two-letter codes
-               if one exists otherwise use the three letter code */
-            String[] tempLanguages = {
-                "aa",  "ab",  "ace", "ach", "ada", "ady", "ae",  "af",  "afa",
-                "afh", "ak",  "akk", "ale", "alg", "am",  "an",  "ang", "apa",
-                "ar",  "arc", "arn", "arp", "art", "arw", "as",  "ast",
-                "ath", "aus", "av",  "awa", "ay",  "az",  "ba",  "bad",
-                "bai", "bal", "ban", "bas", "bat", "be",  "bej",
-                "bem", "ber", "bg",  "bh",  "bho", "bi",  "bik", "bin",
-                "bla", "bm",  "bn",  "bnt", "bo",  "br",  "bra", "bs",
-                "btk", "bua", "bug", "byn", "ca",  "cad", "cai", "car", "cau",
-                "ce",  "ceb", "cel", "ch",  "chb", "chg", "chk", "chm",
-                "chn", "cho", "chp", "chr", "chy", "cmc", "co",  "cop",
-                "cpe", "cpf", "cpp", "cr",  "crh", "crp", "cs",  "csb", "cu",  "cus",
-                "cv",  "cy",  "da",  "dak", "dar", "day", "de",  "del", "den",
-                "dgr", "din", "doi", "dra", "dsb", "dua", "dum", "dv",  "dyu",
-                "dz",  "ee",  "efi", "egy", "eka", "el",  "elx", "en",
-                "enm", "eo",  "es",  "et",  "eu",  "ewo", "fa",
-                "fan", "fat", "ff",  "fi",  "fiu", "fj",  "fo",  "fon",
-                "fr",  "frm", "fro", "fur", "fy",  "ga",  "gaa", "gay",
-                "gba", "gd",  "gem", "gez", "gil", "gl",  "gmh", "gn",
-                "goh", "gon", "gor", "got", "grb", "grc", "gu",  "gv",
-                "gwi", "ha",  "hai", "haw", "he",  "hi",  "hil", "him",
-                "hit", "hmn", "ho",  "hr",  "hsb", "ht",  "hu",  "hup", "hy",  "hz",
-                "ia",  "iba", "id",  "ie",  "ig",  "ii",  "ijo", "ik",
-                "ilo", "inc", "ine", "inh", "io",  "ira", "iro", "is",  "it",
-                "iu",  "ja",  "jbo", "jpr", "jrb", "jv",  "ka",  "kaa", "kab",
-                "kac", "kam", "kar", "kaw", "kbd", "kg",  "kha", "khi",
-                "kho", "ki",  "kj",  "kk",  "kl",  "km",  "kmb", "kn",
-                "ko",  "kok", "kos", "kpe", "kr",  "krc", "kro", "kru", "ks",
-                "ku",  "kum", "kut", "kv",  "kw",  "ky",  "la",  "lad",
-                "lah", "lam", "lb",  "lez", "lg",  "li",  "ln",  "lo",  "lol",
-                "loz", "lt",  "lu",  "lua", "lui", "lun", "luo", "lus",
-                "lv",  "mad", "mag", "mai", "mak", "man", "map", "mas",
-                "mdf", "mdr", "men", "mg",  "mga", "mh",  "mi",  "mic", "min",
-                "mis", "mk",  "mkh", "ml",  "mn",  "mnc", "mni", "mno",
-                "mo",  "moh", "mos", "mr",  "ms",  "mt",  "mul", "mun",
-                "mus", "mwr", "my",  "myn", "myv", "na",  "nah", "nai", "nap",
-                "nb",  "nd",  "nds", "ne",  "new", "ng",  "nia", "nic",
-                "niu", "nl",  "nn",  "no",  "nog", "non", "nr",  "nso", "nub",
-                "nv",  "nwc", "ny",  "nym", "nyn", "nyo", "nzi", "oc",  "oj",
-                "om",  "or",  "os",  "osa", "ota", "oto", "pa",  "paa",
-                "pag", "pal", "pam", "pap", "pau", "peo", "phi", "phn",
-                "pi",  "pl",  "pon", "pra", "pro", "ps",  "pt",  "qu",
-                "raj", "rap", "rar", "rm",  "rn",  "ro",  "roa", "rom",
-                "ru",  "rup", "rw",  "sa",  "sad", "sah", "sai", "sal", "sam",
-                "sas", "sat", "sc",  "sco", "sd",  "se",  "sel", "sem",
-                "sg",  "sga", "sgn", "shn", "si",  "sid", "sio", "sit",
-                "sk",  "sl",  "sla", "sm",  "sma", "smi", "smj", "smn",
-                "sms", "sn",  "snk", "so",  "sog", "son", "sq",  "sr",
-                "srr", "ss",  "ssa", "st",  "su",  "suk", "sus", "sux",
-                "sv",  "sw",  "syr", "ta",  "tai", "te",  "tem", "ter",
-                "tet", "tg",  "th",  "ti",  "tig", "tiv", "tk",  "tkl",
-                "tl",  "tlh", "tli", "tmh", "tn",  "to",  "tog", "tpi", "tr",
-                "ts",  "tsi", "tt",  "tum", "tup", "tut", "tvl", "tw",
-                "ty",  "tyv", "udm", "ug",  "uga", "uk",  "umb", "und", "ur",
-                "uz",  "vai", "ve",  "vi",  "vo",  "vot", "wa",  "wak",
-                "wal", "war", "was", "wen", "wo",  "xal", "xh",  "yao", "yap",
-                "yi",  "yo",  "ypk", "za",  "zap", "zen", "zh",  "znd",
-                "zu",  "zun",
-            };
-
-            String[] tempReplacementLanguages = {
-                "id", "he", "yi", "jv", "sr", "nb",/* replacement language codes */
-            };
-
-            String[] tempObsoleteLanguages = {
-                "in", "iw", "ji", "jw", "sh", "no",    /* obsolete language codes */
-            };
-
-            /* This list MUST contain a three-letter code for every two-letter code in the
-               list above, and they MUST ne in the same order (i.e., the same language must
-               be in the same place in both lists)! */
-            String[] tempLanguages3 = {
-                /*"aa",  "ab",  "ace", "ach", "ada", "ady", "ae",  "af",  "afa",    */
-                "aar", "abk", "ace", "ach", "ada", "ady", "ave", "afr", "afa",
-                /*"afh", "ak",  "akk", "ale", "alg", "am",  "an",  "ang", "apa",    */
-                "afh", "aka", "akk", "ale", "alg", "amh", "arg", "ang", "apa",
-                /*"ar",  "arc", "arn", "arp", "art", "arw", "as",  "ast",    */
-                "ara", "arc", "arn", "arp", "art", "arw", "asm", "ast",
-                /*"ath", "aus", "av",  "awa", "ay",  "az",  "ba",  "bad",    */
-                "ath", "aus", "ava", "awa", "aym", "aze", "bak", "bad",
-                /*"bai", "bal", "ban", "bas", "bat", "be",  "bej",    */
-                "bai", "bal", "ban", "bas", "bat", "bel", "bej",
-                /*"bem", "ber", "bg",  "bh",  "bho", "bi",  "bik", "bin",    */
-                "bem", "ber", "bul", "bih", "bho", "bis", "bik", "bin",
-                /*"bla", "bm",  "bn",  "bnt", "bo",  "br",  "bra", "bs",     */
-                "bla", "bam",  "ben", "bnt", "bod", "bre", "bra", "bos",
-                /*"btk", "bua", "bug", "byn", "ca",  "cad", "cai", "car", "cau",    */
-                "btk", "bua", "bug", "byn", "cat", "cad", "cai", "car", "cau",
-                /*"ce",  "ceb", "cel", "ch",  "chb", "chg", "chk", "chm",    */
-                "che", "ceb", "cel", "cha", "chb", "chg", "chk", "chm",
-                /*"chn", "cho", "chp", "chr", "chy", "cmc", "co",  "cop",    */
-                "chn", "cho", "chp", "chr", "chy", "cmc", "cos", "cop",
-                /*"cpe", "cpf", "cpp", "cr",  "crh", "crp", "cs",  "csb", "cu",  "cus",    */
-                "cpe", "cpf", "cpp", "cre", "crh", "crp", "ces", "csb", "chu", "cus",
-                /*"cv",  "cy",  "da",  "dak", "dar", "day", "de",  "del", "den",    */
-                "chv", "cym", "dan", "dak", "dar", "day", "deu", "del", "den",
-                /*"dgr", "din", "doi", "dra", "dsb", "dua", "dum", "dv",  "dyu",    */
-                "dgr", "din", "doi", "dra", "dsb", "dua", "dum", "div", "dyu",
-                /*"dz",  "ee",  "efi", "egy", "eka", "el",  "elx", "en",     */
-                "dzo", "ewe", "efi", "egy", "eka", "ell", "elx", "eng",
-                /*"enm", "eo",  "es",  "et",  "eu",  "ewo", "fa",     */
-                "enm", "epo", "spa", "est", "eus", "ewo", "fas",
-                /*"fan", "fat", "ff",  "fi",  "fiu", "fj",  "fo",  "fon",    */
-                "fan", "fat", "ful", "fin", "fiu", "fij", "fao", "fon",
-                /*"fr",  "frm", "fro", "fur", "fy",  "ga",  "gaa", "gay",    */
-                "fra", "frm", "fro", "fur", "fry", "gle", "gaa", "gay",
-                /*"gba", "gd",  "gem", "gez", "gil", "gl",  "gmh", "gn",     */
-                "gba", "gla", "gem", "gez", "gil", "glg", "gmh", "grn",
-                /*"goh", "gon", "gor", "got", "grb", "grc", "gu",  "gv",     */
-                "goh", "gon", "gor", "got", "grb", "grc", "guj", "glv",
-                /*"gwi", "ha",  "hai", "haw", "he",  "hi",  "hil", "him",    */
-                "gwi", "hau", "hai", "haw", "heb", "hin", "hil", "him",
-                /*"hit", "hmn", "ho",  "hr",  "hsb", "ht",  "hu",  "hup", "hy",  "hz",     */
-                "hit", "hmn", "hmo", "hrv", "hsb", "hat", "hun", "hup", "hye", "her",
-                /*"ia",  "iba", "id",  "ie",  "ig",  "ii",  "ijo", "ik",     */
-                "ina", "iba", "ind", "ile", "ibo", "iii", "ijo", "ipk",
-                /*"ilo", "inc", "ine", "inh", "io",  "ira", "iro", "is",  "it",      */
-                "ilo", "inc", "ine", "inh", "ido", "ira", "iro", "isl", "ita",
-                /*"iu",  "ja",  "jbo", "jpr", "jrb", "jv",  "ka",  "kaa", "kab",   */
-                "iku", "jpn", "jbo", "jpr", "jrb", "jaw", "kat", "kaa", "kab",
-                /*"kac", "kam", "kar", "kaw", "kbd", "kg",  "kha", "khi",    */
-                "kac", "kam", "kar", "kaw", "kbd", "kon", "kha", "khi",
-                /*"kho", "ki",  "kj",  "kk",  "kl",  "km",  "kmb", "kn",     */
-                "kho", "kik", "kua", "kaz", "kal", "khm", "kmb", "kan",
-                /*"ko",  "kok", "kos", "kpe", "kr",  "krc", "kro", "kru", "ks",     */
-                "kor", "kok", "kos", "kpe", "kau", "krc", "kro", "kru", "kas",
-                /*"ku",  "kum", "kut", "kv",  "kw",  "ky",  "la",  "lad",    */
-                "kur", "kum", "kut", "kom", "cor", "kir", "lat", "lad",
-                /*"lah", "lam", "lb",  "lez", "lg",  "li",  "ln",  "lo",  "lol",    */
-                "lah", "lam", "ltz", "lez", "lug", "lim", "lin", "lao", "lol",
-                /*"loz", "lt",  "lu",  "lua", "lui", "lun", "luo", "lus",    */
-                "loz", "lit", "lub", "lua", "lui", "lun", "luo", "lus",
-                /*"lv",  "mad", "mag", "mai", "mak", "man", "map", "mas",    */
-                "lav", "mad", "mag", "mai", "mak", "man", "map", "mas",
-                /*"mdf", "mdr", "men", "mg",  "mga", "mh",  "mi",  "mic", "min",    */
-                "mdf", "mdr", "men", "mlg", "mga", "mah", "mri", "mic", "min",
-                /*"mis", "mk",  "mkh", "ml",  "mn",  "mnc", "mni", "mno",    */
-                "mis", "mkd", "mkh", "mal", "mon", "mnc", "mni", "mno",
-                /*"mo",  "moh", "mos", "mr",  "ms",  "mt",  "mul", "mun",    */
-                "mol", "moh", "mos", "mar", "msa", "mlt", "mul", "mun",
-                /*"mus", "mwr", "my",  "myn", "myv", "na",  "nah", "nai", "nap",    */
-                "mus", "mwr", "mya", "myn", "myv", "nau", "nah", "nai", "nap",
-                /*"nb",  "nd",  "nds", "ne",  "new", "ng",  "nia", "nic",    */
-                "nob", "nde", "nds", "nep", "new", "ndo", "nia", "nic",
-                /*"niu", "nl",  "nn",  "no",  "nog", "non", "nr",  "nso", "nub",    */
-                "niu", "nld", "nno", "nor", "nog", "non", "nbl", "nso", "nub",
-                /*"nv",  "nwc", "ny",  "nym", "nyn", "nyo", "nzi", "oc",  "oj",     */
-                "nav", "nwc", "nya", "nym", "nyn", "nyo", "nzi", "oci", "oji",
-                /*"om",  "or",  "os",  "osa", "ota", "oto", "pa",  "paa",    */
-                "orm", "ori", "oss", "osa", "ota", "oto", "pan", "paa",
-                /*"pag", "pal", "pam", "pap", "pau", "peo", "phi", "phn",    */
-                "pag", "pal", "pam", "pap", "pau", "peo", "phi", "phn",
-                /*"pi",  "pl",  "pon", "pra", "pro", "ps",  "pt",  "qu",     */
-                "pli", "pol", "pon", "pra", "pro", "pus", "por", "que",
-                /*"raj", "rap", "rar", "rm",  "rn",  "ro",  "roa", "rom",    */
-                "raj", "rap", "rar", "roh", "run", "ron", "roa", "rom",
-                /*"ru",  "rup", "rw",  "sa",  "sad", "sah", "sai", "sal", "sam",    */
-                "rus", "rup", "kin", "san", "sad", "sah", "sai", "sal", "sam",
-                /*"sas", "sat", "sc",  "sco", "sd",  "se",  "sel", "sem",    */
-                "sas", "sat", "srd", "sco", "snd", "sme", "sel", "sem",
-                /*"sg",  "sga", "sgn", "shn", "si",  "sid", "sio", "sit",    */
-                "sag", "sga", "sgn", "shn", "sin", "sid", "sio", "sit",
-                /*"sk",  "sl",  "sla", "sm",  "sma", "smi", "smj", "smn",    */
-                "slk", "slv", "sla", "smo", "sma", "smi", "smj", "smn",
-                /*"sms", "sn",  "snk", "so",  "sog", "son", "sq",  "sr",     */
-                "sms", "sna", "snk", "som", "sog", "son", "sqi", "srp",
-                /*"srr", "ss",  "ssa", "st",  "su",  "suk", "sus", "sux",    */
-                "srr", "ssw", "ssa", "sot", "sun", "suk", "sus", "sux",
-                /*"sv",  "sw",  "syr", "ta",  "tai", "te",  "tem", "ter",    */
-                "swe", "swa", "syr", "tam", "tai", "tel", "tem", "ter",
-                /*"tet", "tg",  "th",  "ti",  "tig", "tiv", "tk",  "tkl",    */
-                "tet", "tgk", "tha", "tir", "tig", "tiv", "tuk", "tkl",
-                /*"tl",  "tlh", "tli", "tmh", "tn",  "to",  "tog", "tpi", "tr",     */
-                "tgl", "tlh", "tli", "tmh", "tsn", "ton", "tog", "tpi", "tur",
-                /*"ts",  "tsi", "tt",  "tum", "tup", "tut", "tvl", "tw",     */
-                "tso", "tsi", "tat", "tum", "tup", "tut", "tvl", "twi",
-                /*"ty",  "tyv", "udm", "ug",  "uga", "uk",  "umb", "und", "ur",     */
-                "tah", "tyv", "udm", "uig", "uga", "ukr", "umb", "und", "urd",
-                /*"uz",  "vai", "ve",  "vi",  "vo",  "vot", "wa",  "wak",    */
-                "uzb", "vai", "ven", "vie", "vol", "vot", "wln", "wak",
-                /*"wal", "war", "was", "wen", "wo",  "xal", "xh",  "yao", "yap",    */
-                "wal", "war", "was", "wen", "wol", "xal", "xho", "yao", "yap",
-                /*"yi",  "yo",  "ypk", "za",  "zap", "zen", "zh",  "znd",    */
-                "yid", "yor", "ypk", "zha", "zap", "zen", "zho", "znd",
-                /*"zu",  "zun",                                              */
-                "zul", "zun",
-            };
-
-            String[] tempObsoleteLanguages3 = {
-                /* "in",  "iw",  "ji",  "jw",  "sh", */
-                "ind", "heb", "yid", "jaw", "srp",
-            };
-
-            synchronized (ULocale.class) {
-                if (_languages == null) {
-                    _languages = tempLanguages;
-                    _replacementLanguages = tempReplacementLanguages;
-                    _obsoleteLanguages = tempObsoleteLanguages;
-                    _languages3 = tempLanguages3;
-                    _obsoleteLanguages3 = tempObsoleteLanguages3;
-                }
-            }
-        }
-    }
-
-    private static String[] _countries;
-    private static String[] _deprecatedCountries;
-    private static String[] _replacementCountries;
-    private static String[] _obsoleteCountries;
-    private static String[] _countries3;
-    private static String[] _obsoleteCountries3;
-
-    // Avoid initializing country tables unless we have to.
-    private static void initCountryTables() {
-        if (_countries == null) {
-            /* ZR(ZAR) is now CD(COD) and FX(FXX) is PS(PSE) as per
-               http://www.evertype.com/standards/iso3166/iso3166-1-en.html
-               added new codes keeping the old ones for compatibility
-               updated to include 1999/12/03 revisions *CWB*/
-
-            /* RO(ROM) is now RO(ROU) according to
-               http://www.iso.org/iso/en/prods-services/iso3166ma/03updates-on-iso-3166/nlv3e-rou.html
-            */
-
-            /* This list MUST be in sorted order, and MUST contain only two-letter codes! */
-            String[] tempCountries = {
-                "AD",  "AE",  "AF",  "AG",  "AI",  "AL",  "AM",  "AN",
-                "AO",  "AQ",  "AR",  "AS",  "AT",  "AU",  "AW",  "AX",  "AZ",
-                "BA",  "BB",  "BD",  "BE",  "BF",  "BG",  "BH",  "BI",
-                "BJ",  "BL",  "BM",  "BN",  "BO",  "BR",  "BS",  "BT",  "BV",
-                "BW",  "BY",  "BZ",  "CA",  "CC",  "CD",  "CF",  "CG",
-                "CH",  "CI",  "CK",  "CL",  "CM",  "CN",  "CO",  "CR",
-                "CU",  "CV",  "CX",  "CY",  "CZ",  "DE",  "DJ",  "DK",
-                "DM",  "DO",  "DZ",  "EC",  "EE",  "EG",  "EH",  "ER",
-                "ES",  "ET",  "FI",  "FJ",  "FK",  "FM",  "FO",  "FR",
-                "GA",  "GB",  "GD",  "GE",  "GF",  "GG",  "GH",  "GI",  "GL",
-                "GM",  "GN",  "GP",  "GQ",  "GR",  "GS",  "GT",  "GU",
-                "GW",  "GY",  "HK",  "HM",  "HN",  "HR",  "HT",  "HU",
-                "ID",  "IE",  "IL",  "IM",  "IN",  "IO",  "IQ",  "IR",  "IS",
-                "IT",  "JE",  "JM",  "JO",  "JP",  "KE",  "KG",  "KH",  "KI",
-                "KM",  "KN",  "KP",  "KR",  "KW",  "KY",  "KZ",  "LA",
-                "LB",  "LC",  "LI",  "LK",  "LR",  "LS",  "LT",  "LU",
-                "LV",  "LY",  "MA",  "MC",  "MD",  "ME",  "MF",  "MG",  "MH",  "MK",
-                "ML",  "MM",  "MN",  "MO",  "MP",  "MQ",  "MR",  "MS",
-                "MT",  "MU",  "MV",  "MW",  "MX",  "MY",  "MZ",  "NA",
-                "NC",  "NE",  "NF",  "NG",  "NI",  "NL",  "NO",  "NP",
-                "NR",  "NU",  "NZ",  "OM",  "PA",  "PE",  "PF",  "PG",
-                "PH",  "PK",  "PL",  "PM",  "PN",  "PR",  "PS",  "PT",
-                "PW",  "PY",  "QA",  "RE",  "RO",  "RS",  "RU",  "RW",  "SA",
-                "SB",  "SC",  "SD",  "SE",  "SG",  "SH",  "SI",  "SJ",
-                "SK",  "SL",  "SM",  "SN",  "SO",  "SR",  "ST",  "SV",
-                "SY",  "SZ",  "TC",  "TD",  "TF",  "TG",  "TH",  "TJ",
-                "TK",  "TL",  "TM",  "TN",  "TO",  "TR",  "TT",  "TV",
-                "TW",  "TZ",  "UA",  "UG",  "UM",  "US",  "UY",  "UZ",
-                "VA",  "VC",  "VE",  "VG",  "VI",  "VN",  "VU",  "WF",
-                "WS",  "YE",  "YT",  "ZA",  "ZM",  "ZW",
-            };
-
-            /* this table is used for 3 letter codes */
-            String[] tempObsoleteCountries = {
-                "FX",  "CS",  "RO",  "TP",  "YU",  "ZR",  /* obsolete country codes */
-            };
-
-            String[] tempDeprecatedCountries = {
-               "BU", "CS", "DY", "FX", "HV", "NH", "RH", "TP", "YU", "ZR" /* deprecated country list */
-            };
-            String[] tempReplacementCountries = {
-           /*  "BU", "CS", "DY", "FX", "HV", "NH", "RH", "TP", "YU", "ZR" */
-               "MM", "RS", "BJ", "FR", "BF", "VU", "ZW", "TL", "RS", "CD",   /* replacement country codes */
-            };
-
-            /* This list MUST contain a three-letter code for every two-letter code in
-               the above list, and they MUST be listed in the same order! */
-            String[] tempCountries3 = {
-                /*  "AD",  "AE",  "AF",  "AG",  "AI",  "AL",  "AM",  "AN",     */
-                    "AND", "ARE", "AFG", "ATG", "AIA", "ALB", "ARM", "ANT",
-                /*  "AO",  "AQ",  "AR",  "AS",  "AT",  "AU",  "AW",  "AX",  "AZ",     */
-                    "AGO", "ATA", "ARG", "ASM", "AUT", "AUS", "ABW", "ALA", "AZE",
-                /*  "BA",  "BB",  "BD",  "BE",  "BF",  "BG",  "BH",  "BI",     */
-                    "BIH", "BRB", "BGD", "BEL", "BFA", "BGR", "BHR", "BDI",
-                /*  "BJ",  "BL",  "BM",  "BN",  "BO",  "BR",  "BS",  "BT",  "BV",     */
-                    "BEN", "BLM", "BMU", "BRN", "BOL", "BRA", "BHS", "BTN", "BVT",
-                /*  "BW",  "BY",  "BZ",  "CA",  "CC",  "CD",  "CF",  "CG",     */
-                    "BWA", "BLR", "BLZ", "CAN", "CCK", "COD", "CAF", "COG",
-                /*  "CH",  "CI",  "CK",  "CL",  "CM",  "CN",  "CO",  "CR",     */
-                    "CHE", "CIV", "COK", "CHL", "CMR", "CHN", "COL", "CRI",
-                /*  "CU",  "CV",  "CX",  "CY",  "CZ",  "DE",  "DJ",  "DK",     */
-                    "CUB", "CPV", "CXR", "CYP", "CZE", "DEU", "DJI", "DNK",
-                /*  "DM",  "DO",  "DZ",  "EC",  "EE",  "EG",  "EH",  "ER",     */
-                    "DMA", "DOM", "DZA", "ECU", "EST", "EGY", "ESH", "ERI",
-                /*  "ES",  "ET",  "FI",  "FJ",  "FK",  "FM",  "FO",  "FR",     */
-                    "ESP", "ETH", "FIN", "FJI", "FLK", "FSM", "FRO", "FRA",
-                /*  "GA",  "GB",  "GD",  "GE",  "GF",  "GG",  "GH",  "GI",  "GL",     */
-                    "GAB", "GBR", "GRD", "GEO", "GUF", "GGY", "GHA", "GIB", "GRL",
-                /*  "GM",  "GN",  "GP",  "GQ",  "GR",  "GS",  "GT",  "GU",     */
-                    "GMB", "GIN", "GLP", "GNQ", "GRC", "SGS", "GTM", "GUM",
-                /*  "GW",  "GY",  "HK",  "HM",  "HN",  "HR",  "HT",  "HU",     */
-                    "GNB", "GUY", "HKG", "HMD", "HND", "HRV", "HTI", "HUN",
-                /*  "ID",  "IE",  "IL",  "IM",  "IN",  "IO",  "IQ",  "IR",  "IS" */
-                    "IDN", "IRL", "ISR", "IMN", "IND", "IOT", "IRQ", "IRN", "ISL",
-                /*  "IT",  "JE",  "JM",  "JO",  "JP",  "KE",  "KG",  "KH",  "KI",     */
-                    "ITA", "JEY", "JAM", "JOR", "JPN", "KEN", "KGZ", "KHM", "KIR",
-                /*  "KM",  "KN",  "KP",  "KR",  "KW",  "KY",  "KZ",  "LA",     */
-                    "COM", "KNA", "PRK", "KOR", "KWT", "CYM", "KAZ", "LAO",
-                /*  "LB",  "LC",  "LI",  "LK",  "LR",  "LS",  "LT",  "LU",     */
-                    "LBN", "LCA", "LIE", "LKA", "LBR", "LSO", "LTU", "LUX",
-                /*  "LV",  "LY",  "MA",  "MC",  "MD",  "ME",  "MF",  "MG",  "MH",  "MK",     */
-                    "LVA", "LBY", "MAR", "MCO", "MDA", "MNE", "MAF", "MDG", "MHL", "MKD",
-                /*  "ML",  "MM",  "MN",  "MO",  "MP",  "MQ",  "MR",  "MS",     */
-                    "MLI", "MMR", "MNG", "MAC", "MNP", "MTQ", "MRT", "MSR",
-                /*  "MT",  "MU",  "MV",  "MW",  "MX",  "MY",  "MZ",  "NA",     */
-                    "MLT", "MUS", "MDV", "MWI", "MEX", "MYS", "MOZ", "NAM",
-                /*  "NC",  "NE",  "NF",  "NG",  "NI",  "NL",  "NO",  "NP",     */
-                    "NCL", "NER", "NFK", "NGA", "NIC", "NLD", "NOR", "NPL",
-                /*  "NR",  "NU",  "NZ",  "OM",  "PA",  "PE",  "PF",  "PG",     */
-                    "NRU", "NIU", "NZL", "OMN", "PAN", "PER", "PYF", "PNG",
-                /*  "PH",  "PK",  "PL",  "PM",  "PN",  "PR",  "PS",  "PT",     */
-                    "PHL", "PAK", "POL", "SPM", "PCN", "PRI", "PSE", "PRT",
-                /*  "PW",  "PY",  "QA",  "RE",  "RO",  "RS",  "RU",  "RW",  "SA",     */
-                    "PLW", "PRY", "QAT", "REU", "ROU", "SRB", "RUS", "RWA", "SAU",
-                /*  "SB",  "SC",  "SD",  "SE",  "SG",  "SH",  "SI",  "SJ",     */
-                    "SLB", "SYC", "SDN", "SWE", "SGP", "SHN", "SVN", "SJM",
-                /*  "SK",  "SL",  "SM",  "SN",  "SO",  "SR",  "ST",  "SV",     */
-                    "SVK", "SLE", "SMR", "SEN", "SOM", "SUR", "STP", "SLV",
-                /*  "SY",  "SZ",  "TC",  "TD",  "TF",  "TG",  "TH",  "TJ",     */
-                    "SYR", "SWZ", "TCA", "TCD", "ATF", "TGO", "THA", "TJK",
-                /*  "TK",  "TL",  "TM",  "TN",  "TO",  "TR",  "TT",  "TV",     */
-                    "TKL", "TLS", "TKM", "TUN", "TON", "TUR", "TTO", "TUV",
-                /*  "TW",  "TZ",  "UA",  "UG",  "UM",  "US",  "UY",  "UZ",     */
-                    "TWN", "TZA", "UKR", "UGA", "UMI", "USA", "URY", "UZB",
-                /*  "VA",  "VC",  "VE",  "VG",  "VI",  "VN",  "VU",  "WF",     */
-                    "VAT", "VCT", "VEN", "VGB", "VIR", "VNM", "VUT", "WLF",
-                /*  "WS",  "YE",  "YT",  "ZA",  "ZM",  "ZW"          */
-                    "WSM", "YEM", "MYT", "ZAF", "ZMB", "ZWE",
-            };
-
-            String[] tempObsoleteCountries3 = {
-                /*"FX",  "CS",  "RO",  "TP",  "YU",  "ZR",   */
-                "FXX", "SCG", "ROM", "TMP", "YUG", "ZAR",
-            };
-
-            synchronized (ULocale.class) {
-                if (_countries == null) {
-                    _countries = tempCountries;
-                    _deprecatedCountries = tempDeprecatedCountries;
-                    _replacementCountries = tempReplacementCountries;
-                    _obsoleteCountries = tempObsoleteCountries;
-                    _countries3 = tempCountries3;
-                    _obsoleteCountries3 = tempObsoleteCountries3;
-                }
-            }
-        }
-    }
-
-    public static String getCurrentCountryID(String oldID){
-        initCountryTables();
-        int offset = findIndex(_deprecatedCountries, oldID);
-        if (offset >= 0) {
-            return _replacementCountries[offset];
-        }
-        return oldID;
-    }
-
-    public static String getCurrentLanguageID(String oldID){
-        initLanguageTables();
-        int offset = findIndex(_obsoleteLanguages, oldID);
-        if (offset >= 0) {
-            return _replacementLanguages[offset];
-        }
-        return oldID;
-    }
-
-
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleUtility.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleUtility.java
deleted file mode 100644
index 07291f7..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/LocaleUtility.java
+++ /dev/null
@@ -1,134 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- ******************************************************************************
- * Copyright (C) 1996-2011, International Business Machines Corporation and   *
- * others. All Rights Reserved.                                               *
- ******************************************************************************
- *
- ******************************************************************************
- */
- 
-package com.ibm.icu.impl;
-
-import java.util.Locale;
-
-/**
- * A class to hold utility functions missing from java.util.Locale.
- */
-public class LocaleUtility {
-
-    /**
-     * A helper function to convert a string of the form
-     * aa_BB_CC to a locale object.  Why isn't this in Locale?
-     */
-    public static Locale getLocaleFromName(String name) {
-        String language = "";
-        String country = "";
-        String variant = "";
-
-        int i1 = name.indexOf('_');
-        if (i1 < 0) {
-            language = name;
-        } else {
-            language = name.substring(0, i1);
-            ++i1;
-            int i2 = name.indexOf('_', i1);
-            if (i2 < 0) {
-                country = name.substring(i1);
-            } else {
-                country = name.substring(i1, i2);
-                variant = name.substring(i2+1);
-            }
-        }
-
-        return new Locale(language, country, variant);
-    }
-
-    /**
-     * Compare two locale strings of the form aa_BB_CC, and
-     * return true if parent is a 'strict' fallback of child, that is,
-     * if child =~ "^parent(_.+)*" (roughly).
-     */
-    public static boolean isFallbackOf(String parent, String child) {
-        if (!child.startsWith(parent)) {
-            return false;
-        }
-        int i = parent.length();
-        return (i == child.length() ||
-                child.charAt(i) == '_');
-    }
-
-    /**
-     * Compare two locales, and return true if the parent is a
-     * 'strict' fallback of the child (parent string is a fallback
-     * of child string).
-     */
-    public static boolean isFallbackOf(Locale parent, Locale child) {
-        return isFallbackOf(parent.toString(), child.toString());
-    }
-
-
-    /*
-     * Convenience method that calls canonicalLocaleString(String) with
-     * locale.toString();
-     */
-    /*public static String canonicalLocaleString(Locale locale) {
-        return canonicalLocaleString(locale.toString());
-    }*/
-
-    /*
-     * You'd think that Locale canonicalizes, since it munges the
-     * renamed languages, but it doesn't quite.  It forces the region
-     * to be upper case but doesn't do anything about the language or
-     * variant.  Our canonical form is 'lower_UPPER_UPPER'.  
-     */
-    /*public static String canonicalLocaleString(String id) {
-        if (id != null) {
-            int x = id.indexOf("_");
-            if (x == -1) {
-                id = id.toLowerCase(Locale.ENGLISH);
-            } else {
-                StringBuffer buf = new StringBuffer();
-                buf.append(id.substring(0, x).toLowerCase(Locale.ENGLISH));
-                buf.append(id.substring(x).toUpperCase(Locale.ENGLISH));
-
-                int len = buf.length();
-                int n = len;
-                while (--n >= 0 && buf.charAt(n) == '_') {
-                }
-                if (++n != len) {
-                    buf.delete(n, len);
-                }
-                id = buf.toString();
-            }
-        }
-        return id;
-    }*/
-
-    /**
-     * Fallback from the given locale name by removing the rightmost _-delimited
-     * element. If there is none, return the root locale ("", "", ""). If this
-     * is the root locale, return null. NOTE: The string "root" is not
-     * recognized; do not use it.
-     * 
-     * @return a new Locale that is a fallback from the given locale, or null.
-     */
-    public static Locale fallback(Locale loc) {
-
-        // Split the locale into parts and remove the rightmost part
-        String[] parts = new String[]
-            { loc.getLanguage(), loc.getCountry(), loc.getVariant() };
-        int i;
-        for (i=2; i>=0; --i) {
-            if (parts[i].length() != 0) {
-                parts[i] = "";
-                break;
-            }
-        }
-        if (i<0) {
-            return null; // All parts were empty
-        }
-        return new Locale(parts[0], parts[1], parts[2]);
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/SimpleCache.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/SimpleCache.java
deleted file mode 100644
index 2e274e6..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/SimpleCache.java
+++ /dev/null
@@ -1,75 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- ****************************************************************************
- * Copyright (c) 2007-2011 International Business Machines Corporation and  *
- * others.  All rights reserved.                                            *
- ****************************************************************************
- */
-
-package com.ibm.icu.impl;
-
-import java.lang.ref.Reference;
-import java.lang.ref.SoftReference;
-import java.lang.ref.WeakReference;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-public class SimpleCache<K, V> implements ICUCache<K, V> {
-    private static final int DEFAULT_CAPACITY = 16;
-
-    private Reference<Map<K, V>> cacheRef = null;
-    private int type = ICUCache.SOFT;
-    private int capacity = DEFAULT_CAPACITY;
-
-    public SimpleCache() {
-    }
-
-    public SimpleCache(int cacheType) {
-        this(cacheType, DEFAULT_CAPACITY);
-    }
-
-    public SimpleCache(int cacheType, int initialCapacity) {
-        if (cacheType == ICUCache.WEAK) {
-            type = cacheType;
-        }
-        if (initialCapacity > 0) {
-            capacity = initialCapacity;
-        }
-    }
-
-    public V get(Object key) {
-        Reference<Map<K, V>> ref = cacheRef;
-        if (ref != null) {
-            Map<K, V> map = ref.get();
-            if (map != null) {
-                return map.get(key);
-            }
-        }
-        return null;
-    }
-
-    public void put(K key, V value) {
-        Reference<Map<K, V>> ref = cacheRef;
-        Map<K, V> map = null;
-        if (ref != null) {
-            map = ref.get();
-        }
-        if (map == null) {
-            map = Collections.synchronizedMap(new HashMap<K, V>(capacity));
-            if (type == ICUCache.WEAK) {
-                ref = new WeakReference<Map<K, V>>(map);
-            } else {
-                ref = new SoftReference<Map<K, V>>(map);
-            }
-            cacheRef = ref;
-        }
-        map.put(key, value);
-    }
-
-    public void clear() {
-        cacheRef = null;
-    }
-
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/AsciiUtil.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/AsciiUtil.java
deleted file mode 100644
index 8bc5dcc..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/AsciiUtil.java
+++ /dev/null
@@ -1,185 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2009-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.impl.locale;
-
-public final class AsciiUtil {
-    public static boolean caseIgnoreMatch(String s1, String s2) {
-        if (s1 == s2) {
-            return true;
-        }
-        int len = s1.length();
-        if (len != s2.length()) {
-            return false;
-        }
-        int i = 0;
-        while (i < len) {
-            char c1 = s1.charAt(i);
-            char c2 = s2.charAt(i);
-            if (c1 != c2 && toLower(c1) != toLower(c2)) {
-                break;
-            }
-            i++;
-        }
-        return (i == len);
-    }
-
-    public static int caseIgnoreCompare(String s1, String s2) {
-        if (s1 == s2) {
-            return 0;
-        }
-        return AsciiUtil.toLowerString(s1).compareTo(AsciiUtil.toLowerString(s2));
-    }
-
-
-    public static char toUpper(char c) {
-        if (c >= 'a' && c <= 'z') {
-            c -= 0x20;
-        }
-        return c;
-    }
-
-    public static char toLower(char c) {
-        if (c >= 'A' && c <= 'Z') {
-            c += 0x20;
-        }
-        return c;
-    }
-
-    public static String toLowerString(String s) {
-        int idx = 0;
-        for (; idx < s.length(); idx++) {
-            char c = s.charAt(idx);
-            if (c >= 'A' && c <= 'Z') {
-                break;
-            }
-        }
-        if (idx == s.length()) {
-            return s;
-        }
-        StringBuilder buf = new StringBuilder(s.substring(0, idx));
-        for (; idx < s.length(); idx++) {
-            buf.append(toLower(s.charAt(idx)));
-        }
-        return buf.toString();
-    }
-
-    public static String toUpperString(String s) {
-        int idx = 0;
-        for (; idx < s.length(); idx++) {
-            char c = s.charAt(idx);
-            if (c >= 'a' && c <= 'z') {
-                break;
-            }
-        }
-        if (idx == s.length()) {
-            return s;
-        }
-        StringBuilder buf = new StringBuilder(s.substring(0, idx));
-        for (; idx < s.length(); idx++) {
-            buf.append(toUpper(s.charAt(idx)));
-        }
-        return buf.toString();
-    }
-
-    public static String toTitleString(String s) {
-        if (s.length() == 0) {
-            return s;
-        }
-        int idx = 0;
-        char c = s.charAt(idx);
-        if (!(c >= 'a' && c <= 'z')) {
-            for (idx = 1; idx < s.length(); idx++) {
-                if (c >= 'A' && c <= 'Z') {
-                    break;
-                }
-            }
-        }
-        if (idx == s.length()) {
-            return s;
-        }
-        StringBuilder buf = new StringBuilder(s.substring(0, idx));
-        if (idx == 0) {
-            buf.append(toUpper(s.charAt(idx)));
-            idx++;
-        }
-        for (; idx < s.length(); idx++) {
-            buf.append(toLower(s.charAt(idx)));
-        }
-        return buf.toString();
-    }
-
-    public static boolean isAlpha(char c) {
-        return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
-    }
-
-    public static boolean isAlphaString(String s) {
-        boolean b = true;
-        for (int i = 0; i < s.length(); i++) {
-            if (!isAlpha(s.charAt(i))) {
-                b = false;
-                break;
-            }
-        }
-        return b;
-    }
-
-    public static boolean isNumeric(char c) {
-        return (c >= '0' && c <= '9');
-    }
-
-    public static boolean isNumericString(String s) {
-        boolean b = true;
-        for (int i = 0; i < s.length(); i++) {
-            if (!isNumeric(s.charAt(i))) {
-                b = false;
-                break;
-            }
-        }
-        return b;
-    }
-
-    public static boolean isAlphaNumeric(char c) {
-        return isAlpha(c) || isNumeric(c);
-    }
-
-    public static boolean isAlphaNumericString(String s) {
-        boolean b = true;
-        for (int i = 0; i < s.length(); i++) {
-            if (!isAlphaNumeric(s.charAt(i))) {
-                b = false;
-                break;
-            }
-        }
-        return b;
-    }
-
-    public static class CaseInsensitiveKey {
-        private String _key;
-        private int _hash;
-
-        public CaseInsensitiveKey(String key) {
-            _key = key;
-            _hash = AsciiUtil.toLowerString(key).hashCode();
-        }
-
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (o instanceof CaseInsensitiveKey) {
-                return AsciiUtil.caseIgnoreMatch(_key, ((CaseInsensitiveKey)o)._key);
-            }
-            return false;
-        }
-
-        public int hashCode() {
-            return _hash;
-        }
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/BaseLocale.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/BaseLocale.java
deleted file mode 100644
index a4ef30d..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/BaseLocale.java
+++ /dev/null
@@ -1,259 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2009-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.impl.locale;
-
-
-public final class BaseLocale {
-
-    private static final boolean JDKIMPL = false;
-
-    public static final String SEP = "_";
-
-    private static final Cache CACHE = new Cache();
-    public static final BaseLocale ROOT = BaseLocale.getInstance("", "", "", "");
-
-    private String _language = "";
-    private String _script = "";
-    private String _region = "";
-    private String _variant = "";
-
-    private transient volatile int _hash = 0;
-
-    private BaseLocale(String language, String script, String region, String variant) {
-        if (language != null) {
-            _language = AsciiUtil.toLowerString(language).intern();
-        }
-        if (script != null) {
-            _script = AsciiUtil.toTitleString(script).intern();
-        }
-        if (region != null) {
-            _region = AsciiUtil.toUpperString(region).intern();
-        }
-        if (variant != null) {
-            if (JDKIMPL) {
-                // preserve upper/lower cases
-                _variant = variant.intern();
-            } else {
-                _variant = AsciiUtil.toUpperString(variant).intern();
-            }
-        }
-    }
-
-    public static BaseLocale getInstance(String language, String script, String region, String variant) {
-        if (JDKIMPL) {
-            // JDK uses deprecated ISO639.1 language codes for he, yi and id
-            if (AsciiUtil.caseIgnoreMatch(language, "he")) {
-                language = "iw";
-            } else if (AsciiUtil.caseIgnoreMatch(language, "yi")) {
-                language = "ji";
-            } else if (AsciiUtil.caseIgnoreMatch(language, "id")) {
-                language = "in";
-            }
-        }
-        Key key = new Key(language, script, region, variant);
-        BaseLocale baseLocale = CACHE.get(key);
-        return baseLocale;
-    }
-
-    public String getLanguage() {
-        return _language;
-    }
-
-    public String getScript() {
-        return _script;
-    }
-
-    public String getRegion() {
-        return _region;
-    }
-
-    public String getVariant() {
-        return _variant;
-    }
-
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof BaseLocale)) {
-            return false;
-        }
-        BaseLocale other = (BaseLocale)obj;
-        return hashCode() == other.hashCode()
-                && _language.equals(other._language)
-                && _script.equals(other._script)
-                && _region.equals(other._region)
-                && _variant.equals(other._variant);
-    }
-
-    public String toString() {
-        StringBuilder buf = new StringBuilder();
-        if (_language.length() > 0) {
-            buf.append("language=");
-            buf.append(_language);
-        }
-        if (_script.length() > 0) {
-            if (buf.length() > 0) {
-                buf.append(", ");
-            }
-            buf.append("script=");
-            buf.append(_script);
-        }
-        if (_region.length() > 0) {
-            if (buf.length() > 0) {
-                buf.append(", ");
-            }
-            buf.append("region=");
-            buf.append(_region);
-        }
-        if (_variant.length() > 0) {
-            if (buf.length() > 0) {
-                buf.append(", ");
-            }
-            buf.append("variant=");
-            buf.append(_variant);
-        }
-        return buf.toString();
-    }
-
-    public int hashCode() {
-        int h = _hash;
-        if (h == 0) {
-            // Generating a hash value from language, script, region and variant
-            for (int i = 0; i < _language.length(); i++) {
-                h = 31*h + _language.charAt(i);
-            }
-            for (int i = 0; i < _script.length(); i++) {
-                h = 31*h + _script.charAt(i);
-            }
-            for (int i = 0; i < _region.length(); i++) {
-                h = 31*h + _region.charAt(i);
-            }
-            for (int i = 0; i < _variant.length(); i++) {
-                h = 31*h + _variant.charAt(i);
-            }
-            _hash = h;
-        }
-        return h;
-    }
-
-    private static class Key implements Comparable<Key> {
-        private String _lang = "";
-        private String _scrt = "";
-        private String _regn = "";
-        private String _vart = "";
-
-        private volatile int _hash; // Default to 0
-
-        public Key(String language, String script, String region, String variant) {
-            if (language != null) {
-                _lang = language;
-            }
-            if (script != null) {
-                _scrt = script;
-            }
-            if (region != null) {
-                _regn = region;
-            }
-            if (variant != null) {
-                _vart = variant;
-            }
-        }
-
-        public boolean equals(Object obj) {
-            if (JDKIMPL) {
-                return (this == obj) ||
-                        (obj instanceof Key)
-                        && AsciiUtil.caseIgnoreMatch(((Key)obj)._lang, this._lang)
-                        && AsciiUtil.caseIgnoreMatch(((Key)obj)._scrt, this._scrt)
-                        && AsciiUtil.caseIgnoreMatch(((Key)obj)._regn, this._regn)
-                        && ((Key)obj)._vart.equals(_vart); // variant is case sensitive in JDK!
-            }
-            return (this == obj) ||
-                    (obj instanceof Key)
-                    && AsciiUtil.caseIgnoreMatch(((Key)obj)._lang, this._lang)
-                    && AsciiUtil.caseIgnoreMatch(((Key)obj)._scrt, this._scrt)
-                    && AsciiUtil.caseIgnoreMatch(((Key)obj)._regn, this._regn)
-                    && AsciiUtil.caseIgnoreMatch(((Key)obj)._vart, this._vart);
-        }
-
-        public int compareTo(Key other) {
-            int res = AsciiUtil.caseIgnoreCompare(this._lang, other._lang);
-            if (res == 0) {
-                res = AsciiUtil.caseIgnoreCompare(this._scrt, other._scrt);
-                if (res == 0) {
-                    res = AsciiUtil.caseIgnoreCompare(this._regn, other._regn);
-                    if (res == 0) {
-                        if (JDKIMPL) {
-                            res = this._vart.compareTo(other._vart);
-                        } else {
-                            res = AsciiUtil.caseIgnoreCompare(this._vart, other._vart);
-                        }
-                    }
-                }
-            }
-            return res;
-        }
-
-        public int hashCode() {
-            int h = _hash;
-            if (h == 0) {
-                // Generating a hash value from language, script, region and variant
-                for (int i = 0; i < _lang.length(); i++) {
-                    h = 31*h + AsciiUtil.toLower(_lang.charAt(i));
-                }
-                for (int i = 0; i < _scrt.length(); i++) {
-                    h = 31*h + AsciiUtil.toLower(_scrt.charAt(i));
-                }
-                for (int i = 0; i < _regn.length(); i++) {
-                    h = 31*h + AsciiUtil.toLower(_regn.charAt(i));
-                }
-                for (int i = 0; i < _vart.length(); i++) {
-                    if (JDKIMPL) {
-                        h = 31*h + _vart.charAt(i);
-                    } else {
-                        h = 31*h + AsciiUtil.toLower(_vart.charAt(i));
-                    }
-                }
-                _hash = h;
-            }
-            return h;
-        }
-
-        public static Key normalize(Key key) {
-            String lang = AsciiUtil.toLowerString(key._lang).intern();
-            String scrt = AsciiUtil.toTitleString(key._scrt).intern();
-            String regn = AsciiUtil.toUpperString(key._regn).intern();
-            String vart;
-            if (JDKIMPL) {
-                // preserve upper/lower cases
-                vart = key._vart.intern();
-            } else {
-                vart = AsciiUtil.toUpperString(key._vart).intern();
-            }
-            return new Key(lang, scrt, regn, vart);
-        }
-    }
-
-    private static class Cache extends LocaleObjectCache<Key, BaseLocale> {
-
-        public Cache() {
-        }
-
-        protected Key normalizeKey(Key key) {
-            return Key.normalize(key);
-        }
-
-        protected BaseLocale createObject(Key key) {
-            return new BaseLocale(key._lang, key._scrt, key._regn, key._vart);
-        }
-
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/Extension.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/Extension.java
deleted file mode 100644
index a6f5206..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/Extension.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2009-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.impl.locale;
-
-
-public class Extension {
-    private char _key;
-    protected String _value;
-
-    protected Extension(char key) {
-        _key = key;
-    }
-
-    Extension(char key, String value) {
-        _key = key;
-        _value = value;
-    }
-
-    public char getKey() {
-        return _key;
-    }
-
-    public String getValue() {
-        return _value;
-    }
-
-    public String getID() {
-        return _key + LanguageTag.SEP + _value;
-    }
-
-    public String toString() {
-        return getID();
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/InternalLocaleBuilder.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/InternalLocaleBuilder.java
deleted file mode 100644
index 7535ddc..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/InternalLocaleBuilder.java
+++ /dev/null
@@ -1,686 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2009-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.impl.locale;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-public final class InternalLocaleBuilder {
-
-    private static final boolean JDKIMPL = false;
-
-    private String _language = "";
-    private String _script = "";
-    private String _region = "";
-    private String _variant = "";
-
-    private static final CaseInsensitiveChar PRIVUSE_KEY = new CaseInsensitiveChar(LanguageTag.PRIVATEUSE.charAt(0));
-
-    private HashMap<CaseInsensitiveChar, String> _extensions;
-    private HashSet<CaseInsensitiveString> _uattributes;
-    private HashMap<CaseInsensitiveString, String> _ukeywords;
-
-
-    public InternalLocaleBuilder() {
-    }
-
-    public InternalLocaleBuilder setLanguage(String language) throws LocaleSyntaxException {
-        if (language == null || language.length() == 0) {
-            _language = "";
-        } else {
-            if (!LanguageTag.isLanguage(language)) {
-                throw new LocaleSyntaxException("Ill-formed language: " + language, 0);
-            }
-            _language = language;
-        }
-        return this;
-    }
-
-    public InternalLocaleBuilder setScript(String script) throws LocaleSyntaxException {
-        if (script == null || script.length() == 0) {
-            _script = "";
-        } else {
-            if (!LanguageTag.isScript(script)) {
-                throw new LocaleSyntaxException("Ill-formed script: " + script, 0);
-            }
-            _script = script;
-        }
-        return this;
-    }
-
-    public InternalLocaleBuilder setRegion(String region) throws LocaleSyntaxException {
-        if (region == null || region.length() == 0) {
-            _region = "";
-        } else {
-            if (!LanguageTag.isRegion(region)) {
-                throw new LocaleSyntaxException("Ill-formed region: " + region, 0);
-            }
-            _region = region;
-        }
-        return this;
-    }
-
-    public InternalLocaleBuilder setVariant(String variant) throws LocaleSyntaxException {
-        if (variant == null || variant.length() == 0) {
-            _variant = "";
-        } else {
-            // normalize separators to "_"
-            String var = variant.replaceAll(LanguageTag.SEP, BaseLocale.SEP);
-            int errIdx = checkVariants(var, BaseLocale.SEP);
-            if (errIdx != -1) {
-                throw new LocaleSyntaxException("Ill-formed variant: " + variant, errIdx);
-            }
-            _variant = var;
-        }
-        return this;
-    }
-
-    public InternalLocaleBuilder addUnicodeLocaleAttribute(String attribute) throws LocaleSyntaxException {
-        if (attribute == null || !UnicodeLocaleExtension.isAttribute(attribute)) {
-            throw new LocaleSyntaxException("Ill-formed Unicode locale attribute: " + attribute);
-        }
-        // Use case insensitive string to prevent duplication
-        if (_uattributes == null) {
-            _uattributes = new HashSet<CaseInsensitiveString>(4);
-        }
-        _uattributes.add(new CaseInsensitiveString(attribute));
-        return this;
-    }
-
-    public InternalLocaleBuilder removeUnicodeLocaleAttribute(String attribute) throws LocaleSyntaxException {
-        if (attribute == null || !UnicodeLocaleExtension.isAttribute(attribute)) {
-            throw new LocaleSyntaxException("Ill-formed Unicode locale attribute: " + attribute);
-        }
-        if (_uattributes != null) {
-            _uattributes.remove(new CaseInsensitiveString(attribute));
-        }
-        return this;
-    }
-
-    public InternalLocaleBuilder setUnicodeLocaleKeyword(String key, String type) throws LocaleSyntaxException {
-        if (!UnicodeLocaleExtension.isKey(key)) {
-            throw new LocaleSyntaxException("Ill-formed Unicode locale keyword key: " + key);
-        }
-
-        CaseInsensitiveString cikey = new CaseInsensitiveString(key);
-        if (type == null) {
-            if (_ukeywords != null) {
-                // null type is used for remove the key
-                _ukeywords.remove(cikey);
-            }
-        } else {
-            if (type.length() != 0) {
-                // normalize separator to "-"
-                String tp = type.replaceAll(BaseLocale.SEP, LanguageTag.SEP);
-                // validate
-                StringTokenIterator itr = new StringTokenIterator(tp, LanguageTag.SEP);
-                while (!itr.isDone()) {
-                    String s = itr.current();
-                    if (!UnicodeLocaleExtension.isTypeSubtag(s)) {
-                        throw new LocaleSyntaxException("Ill-formed Unicode locale keyword type: " + type, itr.currentStart());
-                    }
-                    itr.next();
-                }
-            }
-            if (_ukeywords == null) {
-                _ukeywords = new HashMap<CaseInsensitiveString, String>(4);
-            }
-            _ukeywords.put(cikey, type);
-        }
-        return this;
-    }
-
-    public InternalLocaleBuilder setExtension(char singleton, String value) throws LocaleSyntaxException {
-        // validate key
-        boolean isBcpPrivateuse = LanguageTag.isPrivateusePrefixChar(singleton);
-        if (!isBcpPrivateuse && !LanguageTag.isExtensionSingletonChar(singleton)) {
-            throw new LocaleSyntaxException("Ill-formed extension key: " + singleton);
-        }
-
-        boolean remove = (value == null || value.length() == 0);
-        CaseInsensitiveChar key = new CaseInsensitiveChar(singleton);
-
-        if (remove) {
-            if (UnicodeLocaleExtension.isSingletonChar(key.value())) {
-                // clear entire Unicode locale extension
-                if (_uattributes != null) {
-                    _uattributes.clear();
-                }
-                if (_ukeywords != null) {
-                    _ukeywords.clear();
-                }
-            } else {
-                if (_extensions != null && _extensions.containsKey(key)) {
-                    _extensions.remove(key);
-                }
-            }
-        } else {
-            // validate value
-            String val = value.replaceAll(BaseLocale.SEP, LanguageTag.SEP);
-            StringTokenIterator itr = new StringTokenIterator(val, LanguageTag.SEP);
-            while (!itr.isDone()) {
-                String s = itr.current();
-                boolean validSubtag;
-                if (isBcpPrivateuse) {
-                    validSubtag = LanguageTag.isPrivateuseSubtag(s);
-                } else {
-                    validSubtag = LanguageTag.isExtensionSubtag(s);
-                }
-                if (!validSubtag) {
-                    throw new LocaleSyntaxException("Ill-formed extension value: " + s, itr.currentStart());
-                }
-                itr.next();
-            }
-
-            if (UnicodeLocaleExtension.isSingletonChar(key.value())) {
-                setUnicodeLocaleExtension(val);
-            } else {
-                if (_extensions == null) {
-                    _extensions = new HashMap<CaseInsensitiveChar, String>(4);
-                }
-                _extensions.put(key, val);
-            }
-        }
-        return this;
-    }
-
-    /*
-     * Set extension/private subtags in a single string representation
-     */
-    public InternalLocaleBuilder setExtensions(String subtags) throws LocaleSyntaxException {
-        if (subtags == null || subtags.length() == 0) {
-            clearExtensions();
-            return this;
-        }
-        subtags = subtags.replaceAll(BaseLocale.SEP, LanguageTag.SEP);
-        StringTokenIterator itr = new StringTokenIterator(subtags, LanguageTag.SEP);
-
-        List<String> extensions = null;
-        String privateuse = null;
-
-        int parsed = 0;
-        int start;
-
-        // Make a list of extension subtags
-        while (!itr.isDone()) {
-            String s = itr.current();
-            if (LanguageTag.isExtensionSingleton(s)) {
-                start = itr.currentStart();
-                String singleton = s;
-                StringBuilder sb = new StringBuilder(singleton);
-
-                itr.next();
-                while (!itr.isDone()) {
-                    s = itr.current();
-                    if (LanguageTag.isExtensionSubtag(s)) {
-                        sb.append(LanguageTag.SEP).append(s);
-                        parsed = itr.currentEnd();
-                    } else {
-                        break;
-                    }
-                    itr.next();
-                }
-
-                if (parsed < start) {
-                    throw new LocaleSyntaxException("Incomplete extension '" + singleton + "'", start);
-                }
-
-                if (extensions == null) {
-                    extensions = new ArrayList<String>(4);
-                }
-                extensions.add(sb.toString());
-            } else {
-                break;
-            }
-        }
-        if (!itr.isDone()) {
-            String s = itr.current();
-            if (LanguageTag.isPrivateusePrefix(s)) {
-                start = itr.currentStart();
-                StringBuilder sb = new StringBuilder(s);
-
-                itr.next();
-                while (!itr.isDone()) {
-                    s = itr.current();
-                    if (!LanguageTag.isPrivateuseSubtag(s)) {
-                        break;
-                    }
-                    sb.append(LanguageTag.SEP).append(s);
-                    parsed = itr.currentEnd();
-
-                    itr.next();
-                }
-                if (parsed <= start) {
-                    throw new LocaleSyntaxException("Incomplete privateuse:" + subtags.substring(start), start);
-                } else {
-                    privateuse = sb.toString();
-                }
-            }
-        }
-
-        if (!itr.isDone()) {
-            throw new LocaleSyntaxException("Ill-formed extension subtags:" + subtags.substring(itr.currentStart()), itr.currentStart());
-        }
-
-        return setExtensions(extensions, privateuse);
-    }
-
-    /*
-     * Set a list of BCP47 extensions and private use subtags
-     * BCP47 extensions are already validated and well-formed, but may contain duplicates
-     */
-    private InternalLocaleBuilder setExtensions(List<String> bcpExtensions, String privateuse) {
-        clearExtensions();
-
-        if (bcpExtensions != null && bcpExtensions.size() > 0) {
-            HashSet<CaseInsensitiveChar> processedExtensions = new HashSet<CaseInsensitiveChar>(bcpExtensions.size());
-            for (String bcpExt : bcpExtensions) {
-                CaseInsensitiveChar key = new CaseInsensitiveChar(bcpExt.charAt(0));
-                // ignore duplicates
-                if (!processedExtensions.contains(key)) {
-                    // each extension string contains singleton, e.g. "a-abc-def"
-                    if (UnicodeLocaleExtension.isSingletonChar(key.value())) {
-                        setUnicodeLocaleExtension(bcpExt.substring(2));
-                    } else {
-                        if (_extensions == null) {
-                            _extensions = new HashMap<CaseInsensitiveChar, String>(4);
-                        }
-                        _extensions.put(key, bcpExt.substring(2));
-                    }
-                }
-            }
-        }
-        if (privateuse != null && privateuse.length() > 0) {
-            // privateuse string contains prefix, e.g. "x-abc-def"
-            if (_extensions == null) {
-                _extensions = new HashMap<CaseInsensitiveChar, String>(1);
-            }
-            _extensions.put(new CaseInsensitiveChar(privateuse.charAt(0)), privateuse.substring(2));
-        }
-
-        return this;
-    }
-
-    /*
-     * Reset Builder's internal state with the given language tag
-     */
-    public InternalLocaleBuilder setLanguageTag(LanguageTag langtag) {
-        clear();
-        if (langtag.getExtlangs().size() > 0) {
-            _language = langtag.getExtlangs().get(0);
-        } else {
-            String language = langtag.getLanguage();
-            if (!language.equals(LanguageTag.UNDETERMINED)) {
-                _language = language;
-            }
-        }
-        _script = langtag.getScript();
-        _region = langtag.getRegion();
-
-        List<String> bcpVariants = langtag.getVariants();
-        if (bcpVariants.size() > 0) {
-            StringBuilder var = new StringBuilder(bcpVariants.get(0));
-            for (int i = 1; i < bcpVariants.size(); i++) {
-                var.append(BaseLocale.SEP).append(bcpVariants.get(i));
-            }
-            _variant = var.toString();
-        }
-
-        setExtensions(langtag.getExtensions(), langtag.getPrivateuse());
-
-        return this;
-    }
-
-    public InternalLocaleBuilder setLocale(BaseLocale base, LocaleExtensions extensions) throws LocaleSyntaxException {
-        String language = base.getLanguage();
-        String script = base.getScript();
-        String region = base.getRegion();
-        String variant = base.getVariant();
-
-        if (JDKIMPL) {
-            // Special backward compatibility support
-
-            // Exception 1 - ja_JP_JP
-            if (language.equals("ja") && region.equals("JP") && variant.equals("JP")) {
-                // When locale ja_JP_JP is created, ca-japanese is always there.
-                // The builder ignores the variant "JP"
-                assert("japanese".equals(extensions.getUnicodeLocaleType("ca")));
-                variant = "";
-            }
-            // Exception 2 - th_TH_TH
-            else if (language.equals("th") && region.equals("TH") && variant.equals("TH")) {
-                // When locale th_TH_TH is created, nu-thai is always there.
-                // The builder ignores the variant "TH"
-                assert("thai".equals(extensions.getUnicodeLocaleType("nu")));
-                variant = "";
-            }
-            // Exception 3 - no_NO_NY
-            else if (language.equals("no") && region.equals("NO") && variant.equals("NY")) {
-                // no_NO_NY is a valid locale and used by Java 6 or older versions.
-                // The build ignores the variant "NY" and change the language to "nn".
-                language = "nn";
-                variant = "";
-            }
-        }
-
-        // Validate base locale fields before updating internal state.
-        // LocaleExtensions always store validated/canonicalized values,
-        // so no checks are necessary.
-        if (language.length() > 0 && !LanguageTag.isLanguage(language)) {
-            throw new LocaleSyntaxException("Ill-formed language: " + language);
-        }
-
-        if (script.length() > 0 && !LanguageTag.isScript(script)) {
-            throw new LocaleSyntaxException("Ill-formed script: " + script);
-        }
-
-        if (region.length() > 0 && !LanguageTag.isRegion(region)) {
-            throw new LocaleSyntaxException("Ill-formed region: " + region);
-        }
-
-        if (variant.length() > 0) {
-            int errIdx = checkVariants(variant, BaseLocale.SEP);
-            if (errIdx != -1) {
-                throw new LocaleSyntaxException("Ill-formed variant: " + variant, errIdx);
-            }
-        }
-
-        // The input locale is validated at this point.
-        // Now, updating builder's internal fields.
-        _language = language;
-        _script = script;
-        _region = region;
-        _variant = variant;
-        clearExtensions();
-
-        Set<Character> extKeys = (extensions == null) ? null : extensions.getKeys();
-        if (extKeys != null) {
-            // map extensions back to builder's internal format
-            for (Character key : extKeys) {
-                Extension e = extensions.getExtension(key);
-                if (e instanceof UnicodeLocaleExtension) {
-                    UnicodeLocaleExtension ue = (UnicodeLocaleExtension)e;
-                    for (String uatr : ue.getUnicodeLocaleAttributes()) {
-                        if (_uattributes == null) {
-                            _uattributes = new HashSet<CaseInsensitiveString>(4);
-                        }
-                        _uattributes.add(new CaseInsensitiveString(uatr));
-                    }
-                    for (String ukey : ue.getUnicodeLocaleKeys()) {
-                        if (_ukeywords == null) {
-                            _ukeywords = new HashMap<CaseInsensitiveString, String>(4);
-                        }
-                        _ukeywords.put(new CaseInsensitiveString(ukey), ue.getUnicodeLocaleType(ukey));
-                    }
-                } else {
-                    if (_extensions == null) {
-                        _extensions = new HashMap<CaseInsensitiveChar, String>(4);
-                    }
-                    _extensions.put(new CaseInsensitiveChar(key.charValue()), e.getValue());
-                }
-            }
-        }
-        return this;
-    }
-
-    public InternalLocaleBuilder clear() {
-        _language = "";
-        _script = "";
-        _region = "";
-        _variant = "";
-        clearExtensions();
-        return this;
-    }
-
-    public InternalLocaleBuilder clearExtensions() {
-        if (_extensions != null) {
-            _extensions.clear();
-        }
-        if (_uattributes != null) {
-            _uattributes.clear();
-        }
-        if (_ukeywords != null) {
-            _ukeywords.clear();
-        }
-        return this;
-    }
-
-    public BaseLocale getBaseLocale() {
-        String language = _language;
-        String script = _script;
-        String region = _region;
-        String variant = _variant;
-
-        // Special private use subtag sequence identified by "lvariant" will be
-        // interpreted as Java variant.
-        if (_extensions != null) {
-            String privuse = _extensions.get(PRIVUSE_KEY);
-            if (privuse != null) {
-                StringTokenIterator itr = new StringTokenIterator(privuse, LanguageTag.SEP);
-                boolean sawPrefix = false;
-                int privVarStart = -1;
-                while (!itr.isDone()) {
-                    if (sawPrefix) {
-                        privVarStart = itr.currentStart();
-                        break;
-                    }
-                    if (AsciiUtil.caseIgnoreMatch(itr.current(), LanguageTag.PRIVUSE_VARIANT_PREFIX)) {
-                        sawPrefix = true;
-                    }
-                    itr.next();
-                }
-                if (privVarStart != -1) {
-                    StringBuilder sb = new StringBuilder(variant);
-                    if (sb.length() != 0) {
-                        sb.append(BaseLocale.SEP);
-                    }
-                    sb.append(privuse.substring(privVarStart).replaceAll(LanguageTag.SEP, BaseLocale.SEP));
-                    variant = sb.toString();
-                }
-            }
-        }
-
-        return BaseLocale.getInstance(language, script, region, variant);
-    }
-
-    public LocaleExtensions getLocaleExtensions() {
-        if ((_extensions == null || _extensions.size() == 0)
-                && (_uattributes == null || _uattributes.size() == 0)
-                && (_ukeywords == null || _ukeywords.size() == 0)) {
-            return LocaleExtensions.EMPTY_EXTENSIONS;
-        }
-
-        return new LocaleExtensions(_extensions, _uattributes, _ukeywords);
-    }
-
-    /*
-     * Remove special private use subtag sequence identified by "lvariant"
-     * and return the rest. Only used by LocaleExtensions
-     */
-    static String removePrivateuseVariant(String privuseVal) {
-        StringTokenIterator itr = new StringTokenIterator(privuseVal, LanguageTag.SEP);
-
-        // Note: privateuse value "abc-lvariant" is unchanged
-        // because no subtags after "lvariant".
-
-        int prefixStart = -1;
-        boolean sawPrivuseVar = false;
-        while (!itr.isDone()) {
-            if (prefixStart != -1) {
-                // Note: privateuse value "abc-lvariant" is unchanged
-                // because no subtags after "lvariant".
-                sawPrivuseVar = true;
-                break;
-            }
-            if (AsciiUtil.caseIgnoreMatch(itr.current(), LanguageTag.PRIVUSE_VARIANT_PREFIX)) {
-                prefixStart = itr.currentStart();
-            }
-            itr.next();
-        }
-        if (!sawPrivuseVar) {
-            return privuseVal;
-        }
-
-        assert(prefixStart == 0 || prefixStart > 1);
-        return (prefixStart == 0) ? null : privuseVal.substring(0, prefixStart -1);
-    }
-
-    /*
-     * Check if the given variant subtags separated by the given
-     * separator(s) are valid
-     */
-    private int checkVariants(String variants, String sep) {
-        StringTokenIterator itr = new StringTokenIterator(variants, sep);
-        while (!itr.isDone()) {
-            String s = itr.current();
-            if (!LanguageTag.isVariant(s)) {
-                return itr.currentStart();
-            }
-            itr.next();
-        }
-        return -1;
-    }
-
-    /*
-     * Private methods parsing Unicode Locale Extension subtags.
-     * Duplicated attributes/keywords will be ignored.
-     * The input must be a valid extension subtags (excluding singleton).
-     */
-    private void setUnicodeLocaleExtension(String subtags) {
-        // wipe out existing attributes/keywords
-        if (_uattributes != null) {
-            _uattributes.clear();
-        }
-        if (_ukeywords != null) {
-            _ukeywords.clear();
-        }
-
-        StringTokenIterator itr = new StringTokenIterator(subtags, LanguageTag.SEP);
-
-        // parse attributes
-        while (!itr.isDone()) {
-            if (!UnicodeLocaleExtension.isAttribute(itr.current())) {
-                break;
-            }
-            if (_uattributes == null) {
-                _uattributes = new HashSet<CaseInsensitiveString>(4);
-            }
-            _uattributes.add(new CaseInsensitiveString(itr.current()));
-            itr.next();
-        }
-
-        // parse keywords
-        CaseInsensitiveString key = null;
-        String type;
-        int typeStart = -1;
-        int typeEnd = -1;
-        while (!itr.isDone()) {
-            if (key != null) {
-                if (UnicodeLocaleExtension.isKey(itr.current())) {
-                    // next keyword - emit previous one
-                    assert(typeStart == -1 || typeEnd != -1);
-                    type = (typeStart == -1) ? "" : subtags.substring(typeStart, typeEnd);
-                    if (_ukeywords == null) {
-                        _ukeywords = new HashMap<CaseInsensitiveString, String>(4);
-                    }
-                    _ukeywords.put(key, type);
-
-                    // reset keyword info
-                    CaseInsensitiveString tmpKey = new CaseInsensitiveString(itr.current());
-                    key = _ukeywords.containsKey(tmpKey) ? null : tmpKey;
-                    typeStart = typeEnd = -1;
-                } else {
-                    if (typeStart == -1) {
-                        typeStart = itr.currentStart();
-                    }
-                    typeEnd = itr.currentEnd();
-                }
-            } else if (UnicodeLocaleExtension.isKey(itr.current())) {
-                // 1. first keyword or
-                // 2. next keyword, but previous one was duplicate
-                key = new CaseInsensitiveString(itr.current());
-                if (_ukeywords != null && _ukeywords.containsKey(key)) {
-                    // duplicate
-                    key = null;
-                }
-            }
-
-            if (!itr.hasNext()) {
-                if (key != null) {
-                    // last keyword
-                    assert(typeStart == -1 || typeEnd != -1);
-                    type = (typeStart == -1) ? "" : subtags.substring(typeStart, typeEnd);
-                    if (_ukeywords == null) {
-                        _ukeywords = new HashMap<CaseInsensitiveString, String>(4);
-                    }
-                    _ukeywords.put(key, type);
-                }
-                break;
-            }
-
-            itr.next();
-        }
-    }
-
-    static class CaseInsensitiveString {
-        private String _s;
-
-        CaseInsensitiveString(String s) {
-            _s = s;
-        }
-
-        public String value() {
-            return _s;
-        }
-
-        public int hashCode() {
-            return AsciiUtil.toLowerString(_s).hashCode();
-        }
-
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (!(obj instanceof CaseInsensitiveString)) {
-                return false;
-            }
-            return AsciiUtil.caseIgnoreMatch(_s, ((CaseInsensitiveString)obj).value());
-        }
-    }
-
-    static class CaseInsensitiveChar {
-        private char _c;
-
-        CaseInsensitiveChar(char c) {
-            _c = c;
-        }
-
-        public char value() {
-            return _c;
-        }
-
-        public int hashCode() {
-            return AsciiUtil.toLower(_c);
-        }
-
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (!(obj instanceof CaseInsensitiveChar)) {
-                return false;
-            }
-            return _c ==  AsciiUtil.toLower(((CaseInsensitiveChar)obj).value());
-        }
-
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LanguageTag.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LanguageTag.java
deleted file mode 100644
index e54a5dd..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LanguageTag.java
+++ /dev/null
@@ -1,681 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2010-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.impl.locale;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-public class LanguageTag {
-    private static final boolean JDKIMPL = false;
-
-    //
-    // static fields
-    //
-    public static final String SEP = "-";
-    public static final String PRIVATEUSE = "x";
-    public static String UNDETERMINED = "und";
-    public static final String PRIVUSE_VARIANT_PREFIX = "lvariant";
-
-    //
-    // Language subtag fields
-    //
-    private String _language = "";      // language subtag
-    private String _script = "";        // script subtag
-    private String _region = "";        // region subtag
-    private String _privateuse = "";    // privateuse
-
-    private List<String> _extlangs = Collections.emptyList();   // extlang subtags
-    private List<String> _variants = Collections.emptyList();   // variant subtags
-    private List<String> _extensions = Collections.emptyList(); // extensions
-
-    // The Map contains legacy language tags (marked as “Type: grandfathered” in BCP 47)
-    // and their preferred mappings from BCP 47.
-    private static final Map<AsciiUtil.CaseInsensitiveKey, String[]> LEGACY =
-        new HashMap<AsciiUtil.CaseInsensitiveKey, String[]>();
-
-    static {
-        // legacy        = irregular           ; non-redundant tags registered
-        //               / regular             ; during the RFC 3066 era
-        //
-        // irregular     = "en-GB-oed"         ; irregular tags do not match
-        //               / "i-ami"             ; the 'langtag' production and
-        //               / "i-bnn"             ; would not otherwise be
-        //               / "i-default"         ; considered 'well-formed'
-        //               / "i-enochian"        ; These tags are all valid,
-        //               / "i-hak"             ; but most are deprecated
-        //               / "i-klingon"         ; in favor of more modern
-        //               / "i-lux"             ; subtags or subtag
-        //               / "i-mingo"           ; combination
-        //               / "i-navajo"
-        //               / "i-pwn"
-        //               / "i-tao"
-        //               / "i-tay"
-        //               / "i-tsu"
-        //               / "sgn-BE-FR"
-        //               / "sgn-BE-NL"
-        //               / "sgn-CH-DE"
-        //
-        // regular       = "art-lojban"        ; these tags match the 'langtag'
-        //               / "cel-gaulish"       ; production, but their subtags
-        //               / "no-bok"            ; are not extended language
-        //               / "no-nyn"            ; or variant subtags: their meaning
-        //               / "zh-guoyu"          ; is defined by their registration
-        //               / "zh-hakka"          ; and all of these are deprecated
-        //               / "zh-min"            ; in favor of a more modern
-        //               / "zh-min-nan"        ; subtag or sequence of subtags
-        //               / "zh-xiang"
-
-        final String[][] entries = {
-          //{"tag",         "preferred"},
-            {"art-lojban",  "jbo"},
-            {"cel-gaulish", "xtg-x-cel-gaulish"},   // fallback
-            {"en-GB-oed",   "en-GB-x-oed"},         // fallback
-            {"i-ami",       "ami"},
-            {"i-bnn",       "bnn"},
-            {"i-default",   "en-x-i-default"},      // fallback
-            {"i-enochian",  "und-x-i-enochian"},    // fallback
-            {"i-hak",       "hak"},
-            {"i-klingon",   "tlh"},
-            {"i-lux",       "lb"},
-            {"i-mingo",     "see-x-i-mingo"},       // fallback
-            {"i-navajo",    "nv"},
-            {"i-pwn",       "pwn"},
-            {"i-tao",       "tao"},
-            {"i-tay",       "tay"},
-            {"i-tsu",       "tsu"},
-            {"no-bok",      "nb"},
-            {"no-nyn",      "nn"},
-            {"sgn-BE-FR",   "sfb"},
-            {"sgn-BE-NL",   "vgt"},
-            {"sgn-CH-DE",   "sgg"},
-            {"zh-guoyu",    "cmn"},
-            {"zh-hakka",    "hak"},
-            {"zh-min",      "nan-x-zh-min"},        // fallback
-            {"zh-min-nan",  "nan"},
-            {"zh-xiang",    "hsn"},
-        };
-        for (String[] e : entries) {
-            LEGACY.put(new AsciiUtil.CaseInsensitiveKey(e[0]), e);
-        }
-    }
-
-    private LanguageTag() {
-    }
-
-    /**
-     * See BCP 47 “Tags for Identifying Languages”:
-     * https://www.rfc-editor.org/info/bcp47 -->
-     * https://www.rfc-editor.org/rfc/rfc5646.html#section-2.1
-     */
-    public static LanguageTag parse(String languageTag, ParseStatus sts) {
-        if (sts == null) {
-            sts = new ParseStatus();
-        } else {
-            sts.reset();
-        }
-
-        StringTokenIterator itr;
-
-        String[] gfmap = LEGACY.get(new AsciiUtil.CaseInsensitiveKey(languageTag));
-        if (gfmap != null) {
-            // use preferred mapping
-            itr = new StringTokenIterator(gfmap[1], SEP);
-        } else {
-            itr = new StringTokenIterator(languageTag, SEP);
-        }
-
-        LanguageTag tag = new LanguageTag();
-
-        // langtag must start with either language or privateuse
-        if (tag.parseLanguage(itr, sts)) {
-            tag.parseExtlangs(itr, sts);
-            tag.parseScript(itr, sts);
-            tag.parseRegion(itr, sts);
-            tag.parseVariants(itr, sts);
-            tag.parseExtensions(itr, sts);
-        }
-        tag.parsePrivateuse(itr, sts);
-
-        if (!itr.isDone() && !sts.isError()) {
-            String s = itr.current();
-            sts._errorIndex = itr.currentStart();
-            if (s.length() == 0) {
-                sts._errorMsg = "Empty subtag";
-            } else {
-                sts._errorMsg = "Invalid subtag: " + s; 
-            }
-        }
-
-        return tag;
-    }
-
-    //
-    // Language subtag parsers
-    //
-
-    private boolean parseLanguage(StringTokenIterator itr, ParseStatus sts) {
-        if (itr.isDone() || sts.isError()) {
-            return false;
-        }
-
-        boolean found = false;
-
-        String s = itr.current();
-        if (isLanguage(s)) {
-            found = true;
-            _language = s;
-            sts._parseLength = itr.currentEnd();
-            itr.next();
-        }
-
-        return found;
-    }
-
-    private boolean parseExtlangs(StringTokenIterator itr, ParseStatus sts) {
-        if (itr.isDone() || sts.isError()) {
-            return false;
-        }
-
-        boolean found = false;
-
-        while (!itr.isDone()) {
-            String s = itr.current();
-            if (!isExtlang(s)) {
-                break;
-            }
-            found = true;
-            if (_extlangs.isEmpty()) {
-                _extlangs = new ArrayList<String>(3);
-            }
-            _extlangs.add(s);
-            sts._parseLength = itr.currentEnd();
-            itr.next();
-
-            if (_extlangs.size() == 3) {
-                // Maximum 3 extlangs
-                break;
-            }
-        }
-
-        return found;
-    }
-
-    private boolean parseScript(StringTokenIterator itr, ParseStatus sts) {
-        if (itr.isDone() || sts.isError()) {
-            return false;
-        }
-
-        boolean found = false;
-
-        String s = itr.current();
-        if (isScript(s)) {
-            found = true;
-            _script = s;
-            sts._parseLength = itr.currentEnd();
-            itr.next();
-        }
-
-        return found;
-    }
-
-    private boolean parseRegion(StringTokenIterator itr, ParseStatus sts) {
-        if (itr.isDone() || sts.isError()) {
-            return false;
-        }
-
-        boolean found = false;
-
-        String s = itr.current();
-        if (isRegion(s)) {
-            found = true;
-            _region = s;
-            sts._parseLength = itr.currentEnd();
-            itr.next();
-        }
-
-        return found;
-    }
-
-    private boolean parseVariants(StringTokenIterator itr, ParseStatus sts) {
-        if (itr.isDone() || sts.isError()) {
-            return false;
-        }
-
-        boolean found = false;
-
-        while (!itr.isDone()) {
-            String s = itr.current();
-            if (!isVariant(s)) {
-                break;
-            }
-            found = true;
-            if (_variants.isEmpty()) {
-                _variants = new ArrayList<String>(3);
-            }
-            _variants.add(s);
-            sts._parseLength = itr.currentEnd();
-            itr.next();
-        }
-
-        return found;
-    }
-
-    private boolean parseExtensions(StringTokenIterator itr, ParseStatus sts) {
-        if (itr.isDone() || sts.isError()) {
-            return false;
-        }
-
-        boolean found = false;
-
-        while (!itr.isDone()) {
-            String s = itr.current();
-            if (isExtensionSingleton(s)) {
-                int start = itr.currentStart();
-                String singleton = s;
-                StringBuilder sb = new StringBuilder(singleton);
-
-                itr.next();
-                while (!itr.isDone()) {
-                    s = itr.current();
-                    if (isExtensionSubtag(s)) {
-                        sb.append(SEP).append(s);
-                        sts._parseLength = itr.currentEnd();
-                    } else {
-                        break;
-                    }
-                    itr.next();
-                }
-
-                if (sts._parseLength <= start) {
-                    sts._errorIndex = start;
-                    sts._errorMsg = "Incomplete extension '" + singleton + "'";
-                    break;
-                }
-
-                if (_extensions.size() == 0) {
-                    _extensions = new ArrayList<String>(4);
-                }
-                _extensions.add(sb.toString());
-                found = true;
-            } else {
-                break;
-            }
-        }
-        return found;
-    }
-
-    private boolean parsePrivateuse(StringTokenIterator itr, ParseStatus sts) {
-        if (itr.isDone() || sts.isError()) {
-            return false;
-        }
-
-        boolean found = false;
-
-        String s = itr.current();
-        if (isPrivateusePrefix(s)) {
-            int start = itr.currentStart();
-            StringBuilder sb = new StringBuilder(s);
-
-            itr.next();
-            while (!itr.isDone()) {
-                s = itr.current();
-                if (!isPrivateuseSubtag(s)) {
-                    break;
-                }
-                sb.append(SEP).append(s);
-                sts._parseLength = itr.currentEnd();
-
-                itr.next();
-            }
-
-            if (sts._parseLength <= start) {
-                // need at least 1 private subtag
-                sts._errorIndex = start;
-                sts._errorMsg = "Incomplete privateuse";
-            } else {
-                _privateuse = sb.toString();
-                found = true;
-            }
-        }
-
-        return found;
-    }
-
-    public static LanguageTag parseLocale(BaseLocale baseLocale, LocaleExtensions localeExtensions) {
-        LanguageTag tag = new LanguageTag();
-
-        String language = baseLocale.getLanguage();
-        String script = baseLocale.getScript();
-        String region = baseLocale.getRegion();
-        String variant = baseLocale.getVariant();
-
-        boolean hasSubtag = false;
-
-        String privuseVar = null;   // store ill-formed variant subtags
-
-        if (language.length() > 0 && isLanguage(language)) {
-            // Convert a deprecated language code used by Java to
-            // a new code
-            if (language.equals("iw")) {
-                language = "he";
-            } else if (language.equals("ji")) {
-                language = "yi";
-            } else if (language.equals("in")) {
-                language = "id";
-            }
-            tag._language = language;
-        }
-
-        if (script.length() > 0 && isScript(script)) {
-            tag._script = canonicalizeScript(script);
-            hasSubtag = true;
-        }
-
-        if (region.length() > 0 && isRegion(region)) {
-            tag._region = canonicalizeRegion(region);
-            hasSubtag = true;
-        }
-
-        if (JDKIMPL) {
-            // Special handling for no_NO_NY - use nn_NO for language tag
-            if (tag._language.equals("no") && tag._region.equals("NO") && variant.equals("NY")) {
-                tag._language = "nn";
-                variant = "";
-            }
-        }
-
-        if (variant.length() > 0) {
-            List<String> variants = null;
-            StringTokenIterator varitr = new StringTokenIterator(variant, BaseLocale.SEP);
-            while (!varitr.isDone()) {
-                String var = varitr.current();
-                if (!isVariant(var)) {
-                    break;
-                }
-                if (variants == null) {
-                    variants = new ArrayList<String>();
-                }
-                if (JDKIMPL) {
-                    variants.add(var);  // Do not canonicalize!
-                } else {
-                    variants.add(canonicalizeVariant(var));
-                }
-                varitr.next();
-            }
-            if (variants != null) {
-                tag._variants = variants;
-                hasSubtag = true;
-            }
-            if (!varitr.isDone()) {
-                // ill-formed variant subtags
-                StringBuilder buf = new StringBuilder();
-                while (!varitr.isDone()) {
-                    String prvv = varitr.current();
-                    if (!isPrivateuseSubtag(prvv)) {
-                        // cannot use private use subtag - truncated
-                        break;
-                    }
-                    if (buf.length() > 0) {
-                        buf.append(SEP);
-                    }
-                    if (!JDKIMPL) {
-                        prvv = AsciiUtil.toLowerString(prvv);
-                    }
-                    buf.append(prvv);
-                    varitr.next();
-                }
-                if (buf.length() > 0) {
-                    privuseVar = buf.toString();
-                }
-            }
-        }
-
-        List<String> extensions = null;
-        String privateuse = null;
-
-        Set<Character> locextKeys = localeExtensions.getKeys();
-        for (Character locextKey : locextKeys) {
-            Extension ext = localeExtensions.getExtension(locextKey);
-            if (isPrivateusePrefixChar(locextKey.charValue())) {
-                privateuse = ext.getValue();
-            } else {
-                if (extensions == null) {
-                    extensions = new ArrayList<String>();
-                }
-                extensions.add(locextKey.toString() + SEP + ext.getValue());
-            }
-        }
-
-        if (extensions != null) {
-            tag._extensions = extensions;
-            hasSubtag = true;
-        }
-
-        // append ill-formed variant subtags to private use
-        if (privuseVar != null) {
-            if (privateuse == null) {
-                privateuse = PRIVUSE_VARIANT_PREFIX + SEP + privuseVar;
-            } else {
-                privateuse = privateuse + SEP + PRIVUSE_VARIANT_PREFIX + SEP + privuseVar.replace(BaseLocale.SEP, SEP);
-            }
-        }
-
-        if (privateuse != null) {
-            tag._privateuse = privateuse;
-        }
-
-        if (tag._language.length() == 0 && (hasSubtag || privateuse == null)) {
-            // use lang "und" when 1) no language is available AND
-            // 2) any of other subtags other than private use are available or
-            // no private use tag is available
-            tag._language = UNDETERMINED;
-        }
-
-        return tag;
-    }
-
-    //
-    // Getter methods for language subtag fields
-    //
-
-    public String getLanguage() {
-        return _language;
-    }
-
-    public List<String> getExtlangs() {
-        return Collections.unmodifiableList(_extlangs);
-    }
-
-    public String getScript() {
-        return _script;
-    }
-
-    public String getRegion() {
-        return _region;
-    }
-
-    public List<String> getVariants() {
-        return Collections.unmodifiableList(_variants);
-    }
-
-    public List<String> getExtensions() {
-        return Collections.unmodifiableList(_extensions);
-    }
-
-    public String getPrivateuse() {
-        return _privateuse;
-    }
-
-    //
-    // Language subtag syntax checking methods
-    //
-
-    public static boolean isLanguage(String s) {
-        // language      = 2*3ALPHA            ; shortest ISO 639 code
-        //                 ["-" extlang]       ; sometimes followed by
-        //                                     ;   extended language subtags
-        //               / 4ALPHA              ; or reserved for future use
-        //               / 5*8ALPHA            ; or registered language subtag
-        return (s.length() >= 2) && (s.length() <= 8) && AsciiUtil.isAlphaString(s);
-    }
-
-    public static boolean isExtlang(String s) {
-        // extlang       = 3ALPHA              ; selected ISO 639 codes
-        //                 *2("-" 3ALPHA)      ; permanently reserved
-        return (s.length() == 3) && AsciiUtil.isAlphaString(s);
-    }
-
-    public static boolean isScript(String s) {
-        // script        = 4ALPHA              ; ISO 15924 code
-        return (s.length() == 4) && AsciiUtil.isAlphaString(s);
-    }
-
-    public static boolean isRegion(String s) {
-        // region        = 2ALPHA              ; ISO 3166-1 code
-        //               / 3DIGIT              ; UN M.49 code
-        return ((s.length() == 2) && AsciiUtil.isAlphaString(s))
-                || ((s.length() == 3) && AsciiUtil.isNumericString(s));
-    }
-
-    public static boolean isVariant(String s) {
-        // variant       = 5*8alphanum         ; registered variants
-        //               / (DIGIT 3alphanum)
-        int len = s.length();
-        if (len >= 5 && len <= 8) {
-            return AsciiUtil.isAlphaNumericString(s);
-        }
-        if (len == 4) {
-            return AsciiUtil.isNumeric(s.charAt(0))
-                    && AsciiUtil.isAlphaNumeric(s.charAt(1))
-                    && AsciiUtil.isAlphaNumeric(s.charAt(2))
-                    && AsciiUtil.isAlphaNumeric(s.charAt(3));
-        }
-        return false;
-    }
-
-    public static boolean isExtensionSingleton(String s) {
-        // singleton     = DIGIT               ; 0 - 9
-        //               / %x41-57             ; A - W
-        //               / %x59-5A             ; Y - Z
-        //               / %x61-77             ; a - w
-        //               / %x79-7A             ; y - z
-
-        return (s.length() == 1)
-                && AsciiUtil.isAlphaString(s)
-                && !AsciiUtil.caseIgnoreMatch(PRIVATEUSE, s);
-    }
-
-    public static boolean isExtensionSingletonChar(char c) {
-        return isExtensionSingleton(String.valueOf(c));
-    }
-
-    public static boolean isExtensionSubtag(String s) {
-        // extension     = singleton 1*("-" (2*8alphanum))
-        return (s.length() >= 2) && (s.length() <= 8) && AsciiUtil.isAlphaNumericString(s);
-    }
-
-    public static boolean isPrivateusePrefix(String s) {
-        // privateuse    = "x" 1*("-" (1*8alphanum))
-        return (s.length() == 1)
-                && AsciiUtil.caseIgnoreMatch(PRIVATEUSE, s);
-    }
-
-    public static boolean isPrivateusePrefixChar(char c) {
-        return (AsciiUtil.caseIgnoreMatch(PRIVATEUSE, String.valueOf(c)));
-    }
-
-    public static boolean isPrivateuseSubtag(String s) {
-        // privateuse    = "x" 1*("-" (1*8alphanum))
-        return (s.length() >= 1) && (s.length() <= 8) && AsciiUtil.isAlphaNumericString(s);
-    }
-
-    //
-    // Language subtag canonicalization methods
-    //
-
-    public static String canonicalizeLanguage(String s) {
-        return AsciiUtil.toLowerString(s);
-    }
-
-    public static String canonicalizeExtlang(String s) {
-        return AsciiUtil.toLowerString(s);
-    }
-
-    public static String canonicalizeScript(String s) {
-        return AsciiUtil.toTitleString(s);
-    }
-
-    public static String canonicalizeRegion(String s) {
-        return AsciiUtil.toUpperString(s);
-    }
-
-    public static String canonicalizeVariant(String s) {
-        return AsciiUtil.toLowerString(s);
-    }
-
-    public static String canonicalizeExtension(String s) {
-        return AsciiUtil.toLowerString(s);
-    }
-
-    public static String canonicalizeExtensionSingleton(String s) {
-        return AsciiUtil.toLowerString(s);
-    }
-
-    public static String canonicalizeExtensionSubtag(String s) {
-        return AsciiUtil.toLowerString(s);
-    }
-
-    public static String canonicalizePrivateuse(String s) {
-        return AsciiUtil.toLowerString(s);
-    }
-
-    public static String canonicalizePrivateuseSubtag(String s) {
-        return AsciiUtil.toLowerString(s);
-    }
-
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        if (_language.length() > 0) {
-            sb.append(_language);
-
-            for (String extlang : _extlangs) {
-                sb.append(SEP).append(extlang);
-            }
-
-            if (_script.length() > 0) {
-                sb.append(SEP).append(_script);
-            }
-
-            if (_region.length() > 0) {
-                sb.append(SEP).append(_region);
-            }
-
-            for (String variant : _extlangs) {
-                sb.append(SEP).append(variant);
-            }
-
-            for (String extension : _extensions) {
-                sb.append(SEP).append(extension);
-            }
-        }
-        if (_privateuse.length() > 0) {
-            if (sb.length() > 0) {
-                sb.append(SEP);
-            }
-            sb.append(_privateuse);
-        }
-
-        return sb.toString();
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LocaleExtensions.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LocaleExtensions.java
deleted file mode 100644
index 1d0626a..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LocaleExtensions.java
+++ /dev/null
@@ -1,223 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2009-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.impl.locale;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-import com.ibm.icu.impl.locale.InternalLocaleBuilder.CaseInsensitiveChar;
-import com.ibm.icu.impl.locale.InternalLocaleBuilder.CaseInsensitiveString;
-
-
-public class LocaleExtensions {
-
-    private SortedMap<Character, Extension> _map;
-    private String _id;
-
-    private static final SortedMap<Character, Extension> EMPTY_MAP =
-        Collections.unmodifiableSortedMap(new TreeMap<Character, Extension>());
-
-    public static final LocaleExtensions EMPTY_EXTENSIONS;
-    public static final LocaleExtensions CALENDAR_JAPANESE;
-    public static final LocaleExtensions NUMBER_THAI;
-
-    static {
-        EMPTY_EXTENSIONS = new LocaleExtensions();
-        EMPTY_EXTENSIONS._id = "";
-        EMPTY_EXTENSIONS._map = EMPTY_MAP;
-
-        CALENDAR_JAPANESE = new LocaleExtensions();
-        CALENDAR_JAPANESE._id = "u-ca-japanese";
-        CALENDAR_JAPANESE._map = new TreeMap<Character, Extension>();
-        CALENDAR_JAPANESE._map.put(Character.valueOf(UnicodeLocaleExtension.SINGLETON), UnicodeLocaleExtension.CA_JAPANESE);
-
-        NUMBER_THAI = new LocaleExtensions();
-        NUMBER_THAI._id = "u-nu-thai";
-        NUMBER_THAI._map = new TreeMap<Character, Extension>();
-        NUMBER_THAI._map.put(Character.valueOf(UnicodeLocaleExtension.SINGLETON), UnicodeLocaleExtension.NU_THAI);
-    }
-
-    private LocaleExtensions() {
-    }
-
-    /*
-     * Package local constructor, only used by InternalLocaleBuilder.
-     */
-    LocaleExtensions(Map<CaseInsensitiveChar, String> extensions,
-            Set<CaseInsensitiveString> uattributes, Map<CaseInsensitiveString, String> ukeywords) {
-        boolean hasExtension = (extensions != null && extensions.size() > 0);
-        boolean hasUAttributes = (uattributes != null && uattributes.size() > 0);
-        boolean hasUKeywords = (ukeywords != null && ukeywords.size() > 0);
-
-        if (!hasExtension && !hasUAttributes && !hasUKeywords) {
-            _map = EMPTY_MAP;
-            _id = "";
-            return;
-        }
-
-        // Build extension map
-        _map = new TreeMap<Character, Extension>();
-        if (hasExtension) {
-            for (Entry<CaseInsensitiveChar, String> ext : extensions.entrySet()) {
-                char key = AsciiUtil.toLower(ext.getKey().value());
-                String value = ext.getValue();
-
-                if (LanguageTag.isPrivateusePrefixChar(key)) {
-                    // we need to exclude special variant in privuateuse, e.g. "x-abc-lvariant-DEF"
-                    value = InternalLocaleBuilder.removePrivateuseVariant(value);
-                    if (value == null) {
-                        continue;
-                    }
-                }
-
-                Extension e = new Extension(key, AsciiUtil.toLowerString(value));
-                _map.put(Character.valueOf(key), e);
-            }
-        }
-
-        if (hasUAttributes || hasUKeywords) {
-            TreeSet<String> uaset = null;
-            TreeMap<String, String> ukmap = null;
-
-            if (hasUAttributes) {
-                uaset = new TreeSet<String>();
-                for (CaseInsensitiveString cis : uattributes) {
-                    uaset.add(AsciiUtil.toLowerString(cis.value()));
-                }
-            }
-
-            if (hasUKeywords) {
-                ukmap = new TreeMap<String, String>();
-                for (Entry<CaseInsensitiveString, String> kwd : ukeywords.entrySet()) {
-                    String key = AsciiUtil.toLowerString(kwd.getKey().value());
-                    String type = AsciiUtil.toLowerString(kwd.getValue());
-                    ukmap.put(key, type);
-                }
-            }
-
-            UnicodeLocaleExtension ule = new UnicodeLocaleExtension(uaset, ukmap);
-            _map.put(Character.valueOf(UnicodeLocaleExtension.SINGLETON), ule);
-        }
-
-        if (_map.size() == 0) {
-            // this could happen when only privuateuse with special variant
-            _map = EMPTY_MAP;
-            _id = "";
-        } else {
-            _id = toID(_map);
-        }
-    }
-
-    public Set<Character> getKeys() {
-        return Collections.unmodifiableSet(_map.keySet());
-    }
-
-    public Extension getExtension(Character key) {
-        return _map.get(Character.valueOf(AsciiUtil.toLower(key.charValue())));
-    }
-
-    public String getExtensionValue(Character key) {
-        Extension ext = _map.get(Character.valueOf(AsciiUtil.toLower(key.charValue())));
-        if (ext == null) {
-            return null;
-        }
-        return ext.getValue();
-    }
-
-    public Set<String> getUnicodeLocaleAttributes() {
-        Extension ext = _map.get(Character.valueOf(UnicodeLocaleExtension.SINGLETON));
-        if (ext == null) {
-            return Collections.emptySet();
-        }
-        assert (ext instanceof UnicodeLocaleExtension);
-        return ((UnicodeLocaleExtension)ext).getUnicodeLocaleAttributes();
-    }
-
-    public Set<String> getUnicodeLocaleKeys() {
-        Extension ext = _map.get(Character.valueOf(UnicodeLocaleExtension.SINGLETON));
-        if (ext == null) {
-            return Collections.emptySet();
-        }
-        assert (ext instanceof UnicodeLocaleExtension);
-        return ((UnicodeLocaleExtension)ext).getUnicodeLocaleKeys();
-    }
-
-    public String getUnicodeLocaleType(String unicodeLocaleKey) {
-        Extension ext = _map.get(Character.valueOf(UnicodeLocaleExtension.SINGLETON));
-        if (ext == null) {
-            return null;
-        }
-        assert (ext instanceof UnicodeLocaleExtension);
-        return ((UnicodeLocaleExtension)ext).getUnicodeLocaleType(AsciiUtil.toLowerString(unicodeLocaleKey));
-    }
-
-    public boolean isEmpty() {
-        return _map.isEmpty();
-    }
-
-    public static boolean isValidKey(char c) {
-        return LanguageTag.isExtensionSingletonChar(c) || LanguageTag.isPrivateusePrefixChar(c);
-    }
-
-    public static boolean isValidUnicodeLocaleKey(String ukey) {
-        return UnicodeLocaleExtension.isKey(ukey);
-    }
-
-    private static String toID(SortedMap<Character, Extension> map) {
-        StringBuilder buf = new StringBuilder();
-        Extension privuse = null;
-        for (Entry<Character, Extension> entry : map.entrySet()) {
-            char singleton = entry.getKey().charValue();
-            Extension extension = entry.getValue();
-            if (LanguageTag.isPrivateusePrefixChar(singleton)) {
-                privuse = extension;
-            } else {
-                if (buf.length() > 0) {
-                    buf.append(LanguageTag.SEP);
-                }
-                buf.append(extension);
-            }
-        }
-        if (privuse != null) {
-            if (buf.length() > 0) {
-                buf.append(LanguageTag.SEP);
-            }
-            buf.append(privuse);
-        }
-        return buf.toString();
-    }
-
-
-    public String toString() {
-        return _id;
-    }
-
-    public String getID() {
-        return _id;
-    }
-
-    public int hashCode() {
-        return _id.hashCode();
-    }
-
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        }
-        if (!(other instanceof LocaleExtensions)) {
-            return false;
-        }
-        return this._id.equals(((LocaleExtensions)other)._id);
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LocaleObjectCache.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LocaleObjectCache.java
deleted file mode 100644
index 92d7318..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LocaleObjectCache.java
+++ /dev/null
@@ -1,85 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2009-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.impl.locale;
-
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
-import java.util.concurrent.ConcurrentHashMap;
-
-public abstract class LocaleObjectCache<K, V> {
-    private ConcurrentHashMap<K, CacheEntry<K, V>> _map;
-    private ReferenceQueue<V> _queue = new ReferenceQueue<V>();
-
-    public LocaleObjectCache() {
-        this(16, 0.75f, 16);
-    }
-
-    public LocaleObjectCache(int initialCapacity, float loadFactor, int concurrencyLevel) {
-        _map = new ConcurrentHashMap<K, CacheEntry<K, V>>(initialCapacity, loadFactor, concurrencyLevel);
-    }
-
-    public V get(K key) {
-        V value = null;
-
-        cleanStaleEntries();
-        CacheEntry<K, V> entry = _map.get(key);
-        if (entry != null) {
-            value = entry.get();
-        }
-        if (value == null) {
-            key = normalizeKey(key);
-            V newVal = createObject(key);
-            if (key == null || newVal == null) {
-                // subclass must return non-null key/value object
-                return null;
-            }
-
-            CacheEntry<K, V> newEntry = new CacheEntry<K, V>(key, newVal, _queue);
-
-            while (value == null) {
-                cleanStaleEntries();
-                entry = _map.putIfAbsent(key, newEntry);
-                if (entry == null) {
-                    value = newVal;
-                    break;
-                } else {
-                    value = entry.get();
-                }
-            }
-        }
-        return value;
-    }
-
-    @SuppressWarnings("unchecked")
-    private void cleanStaleEntries() {
-        CacheEntry<K, V> entry;
-        while ((entry = (CacheEntry<K, V>)_queue.poll()) != null) {
-            _map.remove(entry.getKey());
-        }
-    }
-
-    protected abstract V createObject(K key);
-
-    protected K normalizeKey(K key) {
-        return key;
-    }
-
-    private static class CacheEntry<K, V> extends SoftReference<V> {
-        private K _key;
-
-        CacheEntry(K key, V value, ReferenceQueue<V> queue) {
-            super(value, queue);
-            _key = key;
-        }
-
-        K getKey() {
-            return _key;
-        }
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LocaleSyntaxException.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LocaleSyntaxException.java
deleted file mode 100644
index f0f99d2..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/LocaleSyntaxException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2009-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.impl.locale;
-
-public class LocaleSyntaxException extends Exception {
-
-    private static final long serialVersionUID = 1L;
-
-    private int _index = -1;
-
-    public LocaleSyntaxException(String msg) {
-        this(msg, 0);
-    }
-
-    public LocaleSyntaxException(String msg, int errorIndex) {
-        super(msg);
-        _index = errorIndex;
-    }
-
-    public int getErrorIndex() {
-        return _index;
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/ParseStatus.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/ParseStatus.java
deleted file mode 100644
index 2934f7b..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/ParseStatus.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2010-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.impl.locale;
-
-public class ParseStatus {
-    int _parseLength = 0;
-    int _errorIndex = -1;
-    String _errorMsg = null;
-
-    public void reset() {
-        _parseLength = 0;
-        _errorIndex = -1;
-        _errorMsg = null;
-    }
-
-    public boolean isError() {
-        return (_errorIndex >= 0);
-    }
-
-    public int getErrorIndex() {
-        return _errorIndex;
-    }
-
-    public int getParseLength() {
-        return _parseLength;
-    }
-
-    public String getErrorMessage() {
-        return _errorMsg;
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/StringTokenIterator.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/StringTokenIterator.java
deleted file mode 100644
index 38bd83b..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/StringTokenIterator.java
+++ /dev/null
@@ -1,95 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2009-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.impl.locale;
-
-public class StringTokenIterator {
-    private String _text;
-    private String _dlms;
-
-    private String _token;
-    private int _start;
-    private int _end;
-    private boolean _done;
-
-    public StringTokenIterator(String text, String dlms) {
-        _text = text;
-        _dlms = dlms;
-        setStart(0);
-    }
-
-    public String first() {
-        setStart(0);
-        return _token;
-    }
-
-    public String current() {
-        return _token;
-    }
-
-    public int currentStart() {
-        return _start;
-    }
-
-    public int currentEnd() {
-        return _end;
-    }
-
-    public boolean isDone() {
-        return _done;
-    }
-
-    public String next() {
-        if (hasNext()) {
-            _start = _end + 1;
-            _end = nextDelimiter(_start);
-            _token = _text.substring(_start, _end);
-        } else {
-            _start = _end;
-            _token = null;
-            _done = true;
-        }
-        return _token;
-    }
-
-    public boolean hasNext() {
-        return (_end < _text.length());
-    }
-
-    public StringTokenIterator setStart(int offset) {
-        if (offset > _text.length()) {
-            throw new IndexOutOfBoundsException();
-        }
-        _start = offset;
-        _end = nextDelimiter(_start);
-        _token = _text.substring(_start, _end);
-        _done = false;
-        return this;
-    }
-
-    public StringTokenIterator setText(String text) {
-        _text = text;
-        setStart(0);
-        return this;
-    }
-
-    private int nextDelimiter(int start) {
-        int idx = start;
-        outer: while (idx < _text.length()) {
-            char c = _text.charAt(idx);
-            for (int i = 0; i < _dlms.length(); i++) {
-                if (c == _dlms.charAt(i)) {
-                    break outer;
-                }
-            }
-            idx++;
-        }
-        return idx;
-    }
-}
-
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/UnicodeLocaleExtension.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/UnicodeLocaleExtension.java
deleted file mode 100644
index a69ecef..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/impl/locale/UnicodeLocaleExtension.java
+++ /dev/null
@@ -1,104 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2009-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.impl.locale;
-
-import java.util.Collections;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-public class UnicodeLocaleExtension extends Extension {
-    public static final char SINGLETON = 'u';
-
-    private static final SortedSet<String> EMPTY_SORTED_SET = new TreeSet<String>();
-    private static final SortedMap<String, String> EMPTY_SORTED_MAP = new TreeMap<String, String>();
-
-    private SortedSet<String> _attributes = EMPTY_SORTED_SET;
-    private SortedMap<String, String> _keywords = EMPTY_SORTED_MAP;
-
-    public static final UnicodeLocaleExtension CA_JAPANESE;
-    public static final UnicodeLocaleExtension NU_THAI;
-
-    static {
-        CA_JAPANESE = new UnicodeLocaleExtension();
-        CA_JAPANESE._keywords = new TreeMap<String, String>();
-        CA_JAPANESE._keywords.put("ca", "japanese");
-        CA_JAPANESE._value = "ca-japanese";
-
-        NU_THAI = new UnicodeLocaleExtension();
-        NU_THAI._keywords = new TreeMap<String, String>();
-        NU_THAI._keywords.put("nu", "thai");
-        NU_THAI._value = "nu-thai";
-    }
-
-    private UnicodeLocaleExtension() {
-        super(SINGLETON);
-    }
-
-    UnicodeLocaleExtension(SortedSet<String> attributes, SortedMap<String, String> keywords) {
-        this();
-        if (attributes != null && attributes.size() > 0) {
-            _attributes = attributes;
-        }
-        if (keywords != null && keywords.size() > 0) {
-            _keywords = keywords;
-        }
-
-        if (_attributes.size() > 0 || _keywords.size() > 0) {
-            StringBuilder sb = new StringBuilder();
-            for (String attribute : _attributes) {
-                sb.append(LanguageTag.SEP).append(attribute);
-            }
-            for (Entry<String, String> keyword : _keywords.entrySet()) {
-                String key = keyword.getKey();
-                String value = keyword.getValue();
-
-                sb.append(LanguageTag.SEP).append(key);
-                if (value.length() > 0) {
-                    sb.append(LanguageTag.SEP).append(value);
-                }
-            }
-            _value = sb.substring(1);   // skip leading '-'
-        }
-    }
-
-    public Set<String> getUnicodeLocaleAttributes() {
-        return Collections.unmodifiableSet(_attributes);
-    }
-
-    public Set<String> getUnicodeLocaleKeys() {
-        return Collections.unmodifiableSet(_keywords.keySet());
-    }
-
-    public String getUnicodeLocaleType(String unicodeLocaleKey) {
-        return _keywords.get(unicodeLocaleKey);
-    }
-
-    public static boolean isSingletonChar(char c) {
-        return (SINGLETON == AsciiUtil.toLower(c));
-    }
-
-    public static boolean isAttribute(String s) {
-        // 3*8alphanum
-        return (s.length() >= 3) && (s.length() <= 8) && AsciiUtil.isAlphaNumericString(s);
-    }
-
-    public static boolean isKey(String s) {
-        // 2alphanum
-        return (s.length() == 2) && AsciiUtil.isAlphaNumericString(s);
-    }
-
-    public static boolean isTypeSubtag(String s) {
-        // 3*8alphanum
-        return (s.length() >= 3) && (s.length() <= 8) && AsciiUtil.isAlphaNumericString(s);
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/BigDecimal.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/BigDecimal.java
deleted file mode 100644
index 5edef9b..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/BigDecimal.java
+++ /dev/null
@@ -1,3882 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/* Generated from 'BigDecimal.nrx' 8 Sep 2000 11:10:50 [v2.00] */
-/* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */
-package com.ibm.icu.math;
-
-import java.math.BigInteger;
-
-/* ------------------------------------------------------------------ */
-/* BigDecimal -- Decimal arithmetic for Java                          */
-/* ------------------------------------------------------------------ */
-/* Copyright IBM Corporation, 1996-2011.  All Rights Reserved.       */
-/*                                                                    */
-/* The BigDecimal class provides immutable arbitrary-precision        */
-/* floating point (including integer) decimal numbers.                */
-/*                                                                    */
-/* As the numbers are decimal, there is an exact correspondence       */
-/* between an instance of a BigDecimal object and its String          */
-/* representation; the BigDecimal class provides direct conversions   */
-/* to and from String and character array objects, and well as        */
-/* conversions to and from the Java primitive types (which may not    */
-/* be exact).                                                         */
-/* ------------------------------------------------------------------ */
-/* Notes:                                                             */
-/*                                                                    */
-/* 1. A BigDecimal object is never changed in value once constructed; */
-/*    this avoids the need for locking.  Note in particular that the  */
-/*    mantissa array may be shared between many BigDecimal objects,   */
-/*    so that once exposed it must not be altered.                    */
-/*                                                                    */
-/* 2. This class looks at MathContext class fields directly (for      */
-/*    performance).  It must not and does not change them.            */
-/*                                                                    */
-/* 3. Exponent checking is delayed until finish(), as we know         */
-/*    intermediate calculations cannot cause 31-bit overflow.         */
-/*    [This assertion depends on MAX_DIGITS in MathContext.]          */
-/*                                                                    */
-/* 4. Comments for the public API now follow the javadoc conventions. */
-/*    The NetRexx -comments option is used to pass these comments     */
-/*    through to the generated Java code (with -format, if desired).  */
-/*                                                                    */
-/* 5. System.arraycopy is faster than explicit loop as follows        */
-/*      Mean length 4:  equal                                         */
-/*      Mean length 8:  x2                                            */
-/*      Mean length 16: x3                                            */
-/*      Mean length 24: x4                                            */
-/*    From prior experience, we expect mean length a little below 8,  */
-/*    but arraycopy is still the one to use, in general, until later  */
-/*    measurements suggest otherwise.                                 */
-/*                                                                    */
-/* 6. 'DMSRCN' referred to below is the original (1981) IBM S/370     */
-/*    assembler code implementation of the algorithms below; it is    */
-/*    now called IXXRCN and is available with the OS/390 and VM/ESA   */
-/*    operating systems.                                              */
-/* ------------------------------------------------------------------ */
-/* Change History:                                                    */
-/* 1997.09.02 Initial version (derived from netrexx.lang classes)     */
-/* 1997.09.12 Add lostDigits checking                                 */
-/* 1997.10.06 Change mantissa to a byte array                         */
-/* 1997.11.22 Rework power [did not prepare arguments, etc.]          */
-/* 1997.12.13 multiply did not prepare arguments                      */
-/* 1997.12.14 add did not prepare and align arguments correctly       */
-/* 1998.05.02 0.07 packaging changes suggested by Sun and Oracle      */
-/* 1998.05.21 adjust remainder operator finalization                  */
-/* 1998.06.04 rework to pass MathContext to finish() and round()      */
-/* 1998.06.06 change format to use round(); support rounding modes    */
-/* 1998.06.25 rename to BigDecimal and begin merge                    */
-/*            zero can now have trailing zeros (i.e., exp\=0)         */
-/* 1998.06.28 new methods: movePointXxxx, scale, toBigInteger         */
-/*                         unscaledValue, valueof                     */
-/* 1998.07.01 improve byteaddsub to allow array reuse, etc.           */
-/* 1998.07.01 make null testing explicit to avoid JIT bug [Win32]     */
-/* 1998.07.07 scaled division  [divide(BigDecimal, int, int)]         */
-/* 1998.07.08 setScale, faster equals                                 */
-/* 1998.07.11 allow 1E6 (no sign) <sigh>; new double/float conversion */
-/* 1998.10.12 change package to com.ibm.icu.math                          */
-/* 1998.12.14 power operator no longer rounds RHS [to match ANSI]     */
-/*            add toBigDecimal() and BigDecimal(java.math.BigDecimal) */
-/* 1998.12.29 improve byteaddsub by using table lookup                */
-/* 1999.02.04 lostdigits=0 behaviour rounds instead of digits+1 guard */
-/* 1999.02.05 cleaner code for BigDecimal(char[])                     */
-/* 1999.02.06 add javadoc comments                                    */
-/* 1999.02.11 format() changed from 7 to 2 method form                */
-/* 1999.03.05 null pointer checking is no longer explicit             */
-/* 1999.03.05 simplify; changes from discussion with J. Bloch:        */
-/*            null no longer permitted for MathContext; drop boolean, */
-/*            byte, char, float, short constructor, deprecate double  */
-/*            constructor, no blanks in string constructor, add       */
-/*            offset and length version of char[] constructor;        */
-/*            add valueOf(double); drop booleanValue, charValue;      */
-/*            add ...Exact versions of remaining converters           */
-/* 1999.03.13 add toBigIntegerExact                                   */
-/* 1999.03.13 1.00 release to IBM Centre for Java Technology          */
-/* 1999.05.27 1.01 correct 0-0.2 bug under scaled arithmetic          */
-/* 1999.06.29 1.02 constructors should not allow exponent > 9 digits  */
-/* 1999.07.03 1.03 lost digits should not be checked if digits=0      */
-/* 1999.07.06      lost digits Exception message changed              */
-/* 1999.07.10 1.04 more work on 0-0.2 (scaled arithmetic)             */
-/* 1999.07.17      improve messages from pow method                   */
-/* 1999.08.08      performance tweaks                                 */
-/* 1999.08.15      fastpath in multiply                               */
-/* 1999.11.05 1.05 fix problem in intValueExact [e.g., 5555555555]    */
-/* 1999.12.22 1.06 remove multiply fastpath, and improve performance  */
-/* 2000.01.01      copyright update [Y2K has arrived]                 */
-/* 2000.06.18 1.08 no longer deprecate BigDecimal(double)             */
-/* ------------------------------------------------------------------ */
-
-/**
- * The <code>BigDecimal</code> class implements immutable arbitrary-precision decimal numbers. The methods of the
- * <code>BigDecimal</code> class provide operations for fixed and floating point arithmetic, comparison, format
- * conversions, and hashing.
- * <p>
- * As the numbers are decimal, there is an exact correspondence between an instance of a <code>BigDecimal</code> object
- * and its <code>String</code> representation; the <code>BigDecimal</code> class provides direct conversions to and from
- * <code>String</code> and character array (<code>char[]</code>) objects, as well as conversions to and from the Java
- * primitive types (which may not be exact) and <code>BigInteger</code>.
- * <p>
- * In the descriptions of constructors and methods in this documentation, the value of a <code>BigDecimal</code> number
- * object is shown as the result of invoking the <code>toString()</code> method on the object. The internal
- * representation of a decimal number is neither defined nor exposed, and is not permitted to affect the result of any
- * operation.
- * <p>
- * The floating point arithmetic provided by this class is defined by the ANSI X3.274-1996 standard, and is also
- * documented at <code>http://www2.hursley.ibm.com/decimal</code> <br>
- * <i>[This URL will change.]</i>
- * 
- * <h3>Operator methods</h3>
- * <p>
- * Operations on <code>BigDecimal</code> numbers are controlled by a {@link MathContext} object, which provides the
- * context (precision and other information) for the operation. Methods that can take a <code>MathContext</code>
- * parameter implement the standard arithmetic operators for <code>BigDecimal</code> objects and are known as
- * <i>operator methods</i>. The default settings provided by the constant {@link MathContext#DEFAULT} (<code>digits=9,
- * form=SCIENTIFIC, lostDigits=false, roundingMode=ROUND_HALF_UP</code>) perform general-purpose floating point
- * arithmetic to nine digits of precision. The <code>MathContext</code> parameter must not be <code>null</code>.
- * <p>
- * Each operator method also has a version provided which does not take a <code>MathContext</code> parameter. For this
- * version of each method, the context settings used are <code>digits=0,
- * form=PLAIN, lostDigits=false, roundingMode=ROUND_HALF_UP</code>; these settings perform fixed point arithmetic with
- * unlimited precision, as defined for the original BigDecimal class in Java 1.1 and Java 1.2.
- * <p>
- * For monadic operators, only the optional <code>MathContext</code> parameter is present; the operation acts upon the
- * current object.
- * <p>
- * For dyadic operators, a <code>BigDecimal</code> parameter is always present; it must not be <code>null</code>. The
- * operation acts with the current object being the left-hand operand and the <code>BigDecimal</code> parameter being
- * the right-hand operand.
- * <p>
- * For example, adding two <code>BigDecimal</code> objects referred to by the names <code>award</code> and
- * <code>extra</code> could be written as any of:
- * <p>
- * <code>
- *     award.add(extra)
- * <br>award.add(extra, MathContext.DEFAULT)
- * <br>award.add(extra, acontext)
- * </code>
- * <p>
- * (where <code>acontext</code> is a <code>MathContext</code> object), which would return a <code>BigDecimal</code>
- * object whose value is the result of adding <code>award</code> and <code>extra</code> under the appropriate context
- * settings.
- * <p>
- * When a <code>BigDecimal</code> operator method is used, a set of rules define what the result will be (and, by
- * implication, how the result would be represented as a character string). These rules are defined in the BigDecimal
- * arithmetic documentation (see the URL above), but in summary:
- * <ul>
- * <li>Results are normally calculated with up to some maximum number of significant digits. For example, if the
- * <code>MathContext</code> parameter for an operation were <code>MathContext.DEFAULT</code> then the result would be
- * rounded to 9 digits; the division of 2 by 3 would then result in 0.666666667. <br>
- * You can change the default of 9 significant digits by providing the method with a suitable <code>MathContext</code>
- * object. This lets you calculate using as many digits as you need -- thousands, if necessary. Fixed point (scaled)
- * arithmetic is indicated by using a <code>digits</code> setting of 0 (or omitting the <code>MathContext</code>
- * parameter). <br>
- * Similarly, you can change the algorithm used for rounding from the default "classic" algorithm.
- * <li>
- * In standard arithmetic (that is, when the <code>form</code> setting is not <code>PLAIN</code>), a zero result is
- * always expressed as the single digit <code>'0'</code> (that is, with no sign, decimal point, or exponent part).
- * <li>
- * Except for the division and power operators in standard arithmetic, trailing zeros are preserved (this is in contrast
- * to binary floating point operations and most electronic calculators, which lose the information about trailing zeros
- * in the fractional part of results). <br>
- * So, for example:
- * <p>
- * <code>
- *     new BigDecimal("2.40").add(     new BigDecimal("2"))      =&gt; "4.40"
- * <br>new BigDecimal("2.40").subtract(new BigDecimal("2"))      =&gt; "0.40"
- * <br>new BigDecimal("2.40").multiply(new BigDecimal("2"))      =&gt; "4.80"
- * <br>new BigDecimal("2.40").divide(  new BigDecimal("2"), def) =&gt; "1.2"
- * </code>
- * <p>
- * where the value on the right of the <code>=&gt;</code> would be the result of the operation, expressed as a
- * <code>String</code>, and <code>def</code> (in this and following examples) refers to <code>MathContext.DEFAULT</code>
- * ). This preservation of trailing zeros is desirable for most calculations (including financial calculations). If
- * necessary, trailing zeros may be easily removed using division by 1.
- * <li>
- * In standard arithmetic, exponential form is used for a result depending on its value and the current setting of
- * <code>digits</code> (the default is 9 digits). If the number of places needed before the decimal point exceeds the
- * <code>digits</code> setting, or the absolute value of the number is less than <code>0.000001</code>, then the number
- * will be expressed in exponential notation; thus
- * <p>
- * <code>
- *   new BigDecimal("1e+6").multiply(new BigDecimal("1e+6"), def)
- * </code>
- * <p>
- * results in <code>1E+12</code> instead of <code>1000000000000</code>, and
- * <p>
- * <code>
- *   new BigDecimal("1").divide(new BigDecimal("3E+10"), def)
- * </code>
- * <p>
- * results in <code>3.33333333E-11</code> instead of <code>0.0000000000333333333</code>.
- * <p>
- * The form of the exponential notation (scientific or engineering) is determined by the <code>form</code> setting.
- * <eul>
- * <p>
- * The names of methods in this class follow the conventions established by <code>java.lang.Number</code>,
- * <code>java.math.BigInteger</code>, and <code>java.math.BigDecimal</code> in Java 1.1 and Java 1.2.
- * 
- * @see MathContext
- * @author Mike Cowlishaw
- * @stable ICU 2.0
- */
-
-public class BigDecimal extends java.lang.Number implements java.io.Serializable, java.lang.Comparable<BigDecimal> {
-    // private static final java.lang.String $0="BigDecimal.nrx";
-
-    /* ----- Constants ----- */
-    /* properties constant public */// useful to others
-    /**
-     * The <code>BigDecimal</code> constant "0".
-     * 
-     * @see #ONE
-     * @see #TEN
-     * @stable ICU 2.0
-     */
-    public static final com.ibm.icu.math.BigDecimal ZERO = new com.ibm.icu.math.BigDecimal((long) 0); // use long as we
-                                                                                                      // want the int
-                                                                                                      // constructor
-    // .. to be able to use this, for speed
-
-    /**
-     * The <code>BigDecimal</code> constant "1".
-     * 
-     * @see #TEN
-     * @see #ZERO
-     * @stable ICU 2.0
-     */
-    public static final com.ibm.icu.math.BigDecimal ONE = new com.ibm.icu.math.BigDecimal((long) 1); // use long as we
-                                                                                                     // want the int
-                                                                                                     // constructor
-    // .. to be able to use this, for speed
-
-    /**
-     * The <code>BigDecimal</code> constant "10".
-     * 
-     * @see #ONE
-     * @see #ZERO
-     * @stable ICU 2.0
-     */
-    public static final com.ibm.icu.math.BigDecimal TEN = new com.ibm.icu.math.BigDecimal(10);
-
-    // the rounding modes (copied here for upwards compatibility)
-    /**
-     * Rounding mode to round to a more positive number.
-     * 
-     * @see MathContext#ROUND_CEILING
-     * @stable ICU 2.0
-     */
-    public static final int ROUND_CEILING = com.ibm.icu.math.MathContext.ROUND_CEILING;
-
-    /**
-     * Rounding mode to round towards zero.
-     * 
-     * @see MathContext#ROUND_DOWN
-     * @stable ICU 2.0
-     */
-    public static final int ROUND_DOWN = com.ibm.icu.math.MathContext.ROUND_DOWN;
-
-    /**
-     * Rounding mode to round to a more negative number.
-     * 
-     * @see MathContext#ROUND_FLOOR
-     * @stable ICU 2.0
-     */
-    public static final int ROUND_FLOOR = com.ibm.icu.math.MathContext.ROUND_FLOOR;
-
-    /**
-     * Rounding mode to round to nearest neighbor, where an equidistant value is rounded down.
-     * 
-     * @see MathContext#ROUND_HALF_DOWN
-     * @stable ICU 2.0
-     */
-    public static final int ROUND_HALF_DOWN = com.ibm.icu.math.MathContext.ROUND_HALF_DOWN;
-
-    /**
-     * Rounding mode to round to nearest neighbor, where an equidistant value is rounded to the nearest even neighbor.
-     * 
-     * @see MathContext#ROUND_HALF_EVEN
-     * @stable ICU 2.0
-     */
-    public static final int ROUND_HALF_EVEN = com.ibm.icu.math.MathContext.ROUND_HALF_EVEN;
-
-    /**
-     * Rounding mode to round to nearest neighbor, where an equidistant value is rounded up.
-     * 
-     * @see MathContext#ROUND_HALF_UP
-     * @stable ICU 2.0
-     */
-    public static final int ROUND_HALF_UP = com.ibm.icu.math.MathContext.ROUND_HALF_UP;
-
-    /**
-     * Rounding mode to assert that no rounding is necessary.
-     * 
-     * @see MathContext#ROUND_UNNECESSARY
-     * @stable ICU 2.0
-     */
-    public static final int ROUND_UNNECESSARY = com.ibm.icu.math.MathContext.ROUND_UNNECESSARY;
-
-    /**
-     * Rounding mode to round away from zero.
-     * 
-     * @see MathContext#ROUND_UP
-     * @stable ICU 2.0
-     */
-    public static final int ROUND_UP = com.ibm.icu.math.MathContext.ROUND_UP;
-
-    /* properties constant private */// locals
-    private static final byte ispos = 1; // ind: indicates positive (must be 1)
-    private static final byte iszero = 0; // ind: indicates zero (must be 0)
-    private static final byte isneg = -1; // ind: indicates negative (must be -1)
-    // [later could add NaN, +/- infinity, here]
-
-    private static final int MinExp = -999999999; // minimum exponent allowed
-    private static final int MaxExp = 999999999; // maximum exponent allowed
-    private static final int MinArg = -999999999; // minimum argument integer
-    private static final int MaxArg = 999999999; // maximum argument integer
-
-    private static final com.ibm.icu.math.MathContext plainMC = new com.ibm.icu.math.MathContext(0,
-            com.ibm.icu.math.MathContext.PLAIN); // context for plain unlimited math
-
-    /* properties constant private unused */// present but not referenced
-    // Serialization version
-    private static final long serialVersionUID = 8245355804974198832L;
-
-    // private static final java.lang.String
-    // copyright=" Copyright (c) IBM Corporation 1996, 2000.  All rights reserved. ";
-
-    /* properties static private */
-    // Precalculated constant arrays (used by byteaddsub)
-    private static byte bytecar[] = new byte[(90 + 99) + 1]; // carry/borrow array
-    private static byte bytedig[] = diginit(); // next digit array
-
-    /* ----- Instance properties [all private and immutable] ----- */
-    /* properties private */
-
-    /**
-     * The indicator. This may take the values:
-     * <ul>
-     * <li>ispos -- the number is positive <li>iszero -- the number is zero <li>isneg -- the number is negative
-     * </ul>
-     * 
-     * @serial
-     */
-    private byte ind; // assumed undefined
-    // Note: some code below assumes IND = Sign [-1, 0, 1], at present.
-    // We only need two bits for this, but use a byte [also permits
-    // smooth future extension].
-
-    /**
-     * The formatting style. This may take the values:
-     * <ul>
-     * <li>MathContext.PLAIN -- no exponent needed <li>MathContext.SCIENTIFIC -- scientific notation required <li>
-     * MathContext.ENGINEERING -- engineering notation required
-     * </ul>
-     * <p>
-     * This property is an optimization; it allows us to defer number layout until it is actually needed as a string,
-     * hence avoiding unnecessary formatting.
-     * 
-     * @serial
-     */
-    private byte form = (byte) com.ibm.icu.math.MathContext.PLAIN; // assumed PLAIN
-    // We only need two bits for this, at present, but use a byte
-    // [again, to allow for smooth future extension]
-
-    /**
-     * The value of the mantissa.
-     * <p>
-     * Once constructed, this may become shared between several BigDecimal objects, so must not be altered.
-     * <p>
-     * For efficiency (speed), this is a byte array, with each byte taking a value of 0 -> 9.
-     * <p>
-     * If the first byte is 0 then the value of the number is zero (and mant.length=1, except when constructed from a
-     * plain number, for example, 0.000).
-     * 
-     * @serial
-     */
-    private byte mant[]; // assumed null
-
-    /**
-     * The exponent.
-     * <p>
-     * For fixed point arithmetic, scale is <code>-exp</code>, and can apply to zero.
-     * 
-     * Note that this property can have a value less than MinExp when the mantissa has more than one digit.
-     * 
-     * @serial
-     */
-    private int exp;
-
-    // assumed 0
-
-    /* ---------------------------------------------------------------- */
-    /* Constructors */
-    /* ---------------------------------------------------------------- */
-
-    /**
-     * Constructs a <code>BigDecimal</code> object from a <code>java.math.BigDecimal</code>.
-     * <p>
-     * Constructs a <code>BigDecimal</code> as though the parameter had been represented as a <code>String</code> (using
-     * its <code>toString</code> method) and the {@link #BigDecimal(java.lang.String)} constructor had then been used.
-     * The parameter must not be <code>null</code>.
-     * <p>
-     * <i>(Note: this constructor is provided only in the <code>com.ibm.icu.math</code> version of the BigDecimal class.
-     * It would not be present in a <code>java.math</code> version.)</i>
-     * 
-     * @param bd The <code>BigDecimal</code> to be translated.
-     * @stable ICU 2.0
-     */
-
-    public BigDecimal(java.math.BigDecimal bd) {
-        this(bd.toString());
-        return;
-    }
-
-    /**
-     * Constructs a <code>BigDecimal</code> object from a <code>BigInteger</code>, with scale 0.
-     * <p>
-     * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the <code>BigInteger</code>,
-     * with a scale of zero. The value of the <code>BigDecimal</code> is identical to the value of the <code>BigInteger
-     * </code>. The parameter must not be <code>null</code>.
-     * <p>
-     * The <code>BigDecimal</code> will contain only decimal digits, prefixed with a leading minus sign (hyphen) if the
-     * <code>BigInteger</code> is negative. A leading zero will be present only if the <code>BigInteger</code> is zero.
-     * 
-     * @param bi The <code>BigInteger</code> to be converted.
-     * @stable ICU 2.0
-     */
-
-    public BigDecimal(java.math.BigInteger bi) {
-        this(bi.toString(10));
-        return;
-    }
-
-    // exp remains 0
-
-    /**
-     * Constructs a <code>BigDecimal</code> object from a <code>BigInteger</code> and a scale.
-     * <p>
-     * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the <code>BigInteger</code>,
-     * scaled by the second parameter, which may not be negative. The value of the <code>BigDecimal</code> is the <code>
-     * BigInteger</code> divided by ten to the power of the scale. The <code>BigInteger</code> parameter must not be
-     * <code>null</code>.
-     * <p>
-     * The <code>BigDecimal</code> will contain only decimal digits, (with an embedded decimal point followed by <code>
-     * scale</code> decimal digits if the scale is positive), prefixed with a leading minus sign (hyphen) if the <code>
-     * BigInteger</code> is negative. A leading zero will be present only if the <code>BigInteger</code> is zero.
-     * 
-     * @param bi The <code>BigInteger</code> to be converted.
-     * @param scale The <code>int</code> specifying the scale.
-     * @throws NumberFormatException If the scale is negative.
-     * @stable ICU 2.0
-     */
-
-    public BigDecimal(java.math.BigInteger bi, int scale) {
-        this(bi.toString(10));
-        if (scale < 0)
-            throw new java.lang.NumberFormatException("Negative scale:" + " " + scale);
-        exp = -scale; // exponent is -scale
-        return;
-    }
-
-    /**
-     * Constructs a <code>BigDecimal</code> object from an array of characters.
-     * <p>
-     * Constructs a <code>BigDecimal</code> as though a <code>String</code> had been constructed from the character
-     * array and the {@link #BigDecimal(java.lang.String)} constructor had then been used. The parameter must not be
-     * <code>null</code>.
-     * <p>
-     * Using this constructor is faster than using the <code>BigDecimal(String)</code> constructor if the string is
-     * already available in character array form.
-     * 
-     * @param inchars The <code>char[]</code> array containing the number to be converted.
-     * @throws NumberFormatException If the parameter is not a valid number.
-     * @stable ICU 2.0
-     */
-
-    public BigDecimal(char inchars[]) {
-        this(inchars, 0, inchars.length);
-        return;
-    }
-
-    /**
-     * Constructs a <code>BigDecimal</code> object from an array of characters.
-     * <p>
-     * Constructs a <code>BigDecimal</code> as though a <code>String</code> had been constructed from the character
-     * array (or a subarray of that array) and the {@link #BigDecimal(java.lang.String)} constructor had then been used.
-     * The first parameter must not be <code>null</code>, and the subarray must be wholly contained within it.
-     * <p>
-     * Using this constructor is faster than using the <code>BigDecimal(String)</code> constructor if the string is
-     * already available within a character array.
-     * 
-     * @param inchars The <code>char[]</code> array containing the number to be converted.
-     * @param offset The <code>int</code> offset into the array of the start of the number to be converted.
-     * @param length The <code>int</code> length of the number.
-     * @throws NumberFormatException If the parameter is not a valid number for any reason.
-     * @stable ICU 2.0
-     */
-
-    public BigDecimal(char inchars[], int offset, int length) {
-        super();
-        boolean exotic;
-        boolean hadexp;
-        int d;
-        int dotoff;
-        int last;
-        int i = 0;
-        char si = 0;
-        boolean eneg = false;
-        int k = 0;
-        int elen = 0;
-        int j = 0;
-        char sj = 0;
-        int dvalue = 0;
-        int mag = 0;
-        // This is the primary constructor; all incoming strings end up
-        // here; it uses explicit (inline) parsing for speed and to avoid
-        // generating intermediate (temporary) objects of any kind.
-        // 1998.06.25: exponent form built only if E/e in string
-        // 1998.06.25: trailing zeros not removed for zero
-        // 1999.03.06: no embedded blanks; allow offset and length
-        if (length <= 0)
-            bad(inchars); // bad conversion (empty string)
-        // [bad offset will raise array bounds exception]
-
-        /* Handle and step past sign */
-        ind = ispos; // assume positive
-        if (inchars[offset] == ('-')) {
-            length--;
-            if (length == 0)
-                bad(inchars); // nothing after sign
-            ind = isneg;
-            offset++;
-        } else if (inchars[offset] == ('+')) {
-            length--;
-            if (length == 0)
-                bad(inchars); // nothing after sign
-            offset++;
-        }
-
-        /* We're at the start of the number */
-        exotic = false; // have extra digits
-        hadexp = false; // had explicit exponent
-        d = 0; // count of digits found
-        dotoff = -1; // offset where dot was found
-        last = -1; // last character of mantissa
-        {
-            int $1 = length;
-            i = offset;
-            i: for (; $1 > 0; $1--, i++) {
-                si = inchars[i];
-                if (si >= '0') // test for Arabic digit
-                    if (si <= '9') {
-                        last = i;
-                        d++; // still in mantissa
-                        continue i;
-                    }
-                if (si == '.') { // record and ignore
-                    if (dotoff >= 0)
-                        bad(inchars); // two dots
-                    dotoff = i - offset; // offset into mantissa
-                    continue i;
-                }
-                if (si != 'e')
-                    if (si != 'E') { // expect an extra digit
-                        if ((!(Character.isDigit(si))))
-                            bad(inchars); // not a number
-                        // defer the base 10 check until later to avoid extra method call
-                        exotic = true; // will need conversion later
-                        last = i;
-                        d++; // still in mantissa
-                        continue i;
-                    }
-                /* Found 'e' or 'E' -- now process explicit exponent */
-                // 1998.07.11: sign no longer required
-                if ((i - offset) > (length - 2))
-                    bad(inchars); // no room for even one digit
-                eneg = false;
-                if ((inchars[i + 1]) == ('-')) {
-                    eneg = true;
-                    k = i + 2;
-                } else if ((inchars[i + 1]) == ('+'))
-                    k = i + 2;
-                else
-                    k = i + 1;
-                // k is offset of first expected digit
-                elen = length - ((k - offset)); // possible number of digits
-                if ((elen == 0) | (elen > 9))
-                    bad(inchars); // 0 or more than 9 digits
-                {
-                    int $2 = elen;
-                    j = k;
-                    for (; $2 > 0; $2--, j++) {
-                        sj = inchars[j];
-                        if (sj < '0')
-                            bad(inchars); // always bad
-                        if (sj > '9') { // maybe an exotic digit
-                            if ((!(Character.isDigit(sj))))
-                                bad(inchars); // not a number
-                            dvalue = Character.digit(sj, 10); // check base
-                            if (dvalue < 0)
-                                bad(inchars); // not base 10
-                        } else
-                            dvalue = ((int) (sj)) - ((int) ('0'));
-                        exp = (exp * 10) + dvalue;
-                    }
-                }/* j */
-                if (eneg)
-                    exp = -exp; // was negative
-                hadexp = true; // remember we had one
-                break i; // we are done
-            }
-        }/* i */
-
-        /* Here when all inspected */
-        if (d == 0)
-            bad(inchars); // no mantissa digits
-        if (dotoff >= 0)
-            exp = (exp + dotoff) - d; // adjust exponent if had dot
-
-        /* strip leading zeros/dot (leave final if all 0's) */
-        {
-            int $3 = last - 1;
-            i = offset;
-            i: for (; i <= $3; i++) {
-                si = inchars[i];
-                if (si == '0') {
-                    offset++;
-                    dotoff--;
-                    d--;
-                } else if (si == '.') {
-                    offset++; // step past dot
-                    dotoff--;
-                } else if (si <= '9')
-                    break i;/* non-0 */
-                else {/* exotic */
-                    if ((Character.digit(si, 10)) != 0)
-                        break i; // non-0 or bad
-                    // is 0 .. strip like '0'
-                    offset++;
-                    dotoff--;
-                    d--;
-                }
-            }
-        }/* i */
-
-        /* Create the mantissa array */
-        mant = new byte[d]; // we know the length
-        j = offset; // input offset
-        if (exotic) {
-            do { // slow: check for exotica
-                {
-                    int $4 = d;
-                    i = 0;
-                    for (; $4 > 0; $4--, i++) {
-                        if (i == dotoff)
-                            j++; // at dot
-                        sj = inchars[j];
-                        if (sj <= '9')
-                            mant[i] = (byte) (((int) (sj)) - ((int) ('0')));/* easy */
-                        else {
-                            dvalue = Character.digit(sj, 10);
-                            if (dvalue < 0)
-                                bad(inchars); // not a number after all
-                            mant[i] = (byte) dvalue;
-                        }
-                        j++;
-                    }
-                }/* i */
-            } while (false);
-        }/* exotica */
-        else {
-            do {
-                {
-                    int $5 = d;
-                    i = 0;
-                    for (; $5 > 0; $5--, i++) {
-                        if (i == dotoff)
-                            j++;
-                        mant[i] = (byte) (((int) (inchars[j])) - ((int) ('0')));
-                        j++;
-                    }
-                }/* i */
-            } while (false);
-        }/* simple */
-
-        /* Looks good. Set the sign indicator and form, as needed. */
-        // Trailing zeros are preserved
-        // The rule here for form is:
-        // If no E-notation, then request plain notation
-        // Otherwise act as though add(0,DEFAULT) and request scientific notation
-        // [form is already PLAIN]
-        if (mant[0] == 0) {
-            ind = iszero; // force to show zero
-            // negative exponent is significant (e.g., -3 for 0.000) if plain
-            if (exp > 0)
-                exp = 0; // positive exponent can be ignored
-            if (hadexp) { // zero becomes single digit from add
-                mant = ZERO.mant;
-                exp = 0;
-            }
-        } else { // non-zero
-            // [ind was set earlier]
-            // now determine form
-            if (hadexp) {
-                form = (byte) com.ibm.icu.math.MathContext.SCIENTIFIC;
-                // 1999.06.29 check for overflow
-                mag = (exp + mant.length) - 1; // true exponent in scientific notation
-                if ((mag < MinExp) | (mag > MaxExp))
-                    bad(inchars);
-            }
-        }
-        // say 'BD(c[]): mant[0] mantlen exp ind form:' mant[0] mant.length exp ind form
-        return;
-    }
-
-    /**
-     * Constructs a <code>BigDecimal</code> object directly from a <code>double</code>.
-     * <p>
-     * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the 64-bit signed binary
-     * floating point parameter.
-     * <p>
-     * Note that this constructor it an exact conversion; it does not give the same result as converting <code>num
-     * </code> to a <code>String</code> using the <code>Double.toString()</code> method and then using the
-     * {@link #BigDecimal(java.lang.String)} constructor. To get that result, use the static {@link #valueOf(double)}
-     * method to construct a <code>BigDecimal</code> from a <code>double</code>.
-     * 
-     * @param num The <code>double</code> to be converted.
-     * @throws NumberFormatException If the parameter is infinite or not a number.
-     * @stable ICU 2.0
-     */
-
-    public BigDecimal(double num) {
-        // 1999.03.06: use exactly the old algorithm
-        // 2000.01.01: note that this constructor does give an exact result,
-        // so perhaps it should not be deprecated
-        // 2000.06.18: no longer deprecated
-        this((new java.math.BigDecimal(num)).toString());
-        return;
-    }
-
-    /**
-     * Constructs a <code>BigDecimal</code> object directly from a <code>int</code>.
-     * <p>
-     * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the 32-bit signed binary
-     * integer parameter. The <code>BigDecimal</code> will contain only decimal digits, prefixed with a leading minus
-     * sign (hyphen) if the parameter is negative. A leading zero will be present only if the parameter is zero.
-     * 
-     * @param num The <code>int</code> to be converted.
-     * @stable ICU 2.0
-     */
-
-    public BigDecimal(int num) {
-        super();
-        int mun;
-        int i = 0;
-        // We fastpath commoners
-        if (num <= 9)
-            if (num >= (-9)) {
-                do {
-                    // very common single digit case
-                    {/* select */
-                        if (num == 0) {
-                            mant = ZERO.mant;
-                            ind = iszero;
-                        } else if (num == 1) {
-                            mant = ONE.mant;
-                            ind = ispos;
-                        } else if (num == (-1)) {
-                            mant = ONE.mant;
-                            ind = isneg;
-                        } else {
-                            {
-                                mant = new byte[1];
-                                if (num > 0) {
-                                    mant[0] = (byte) num;
-                                    ind = ispos;
-                                } else { // num<-1
-                                    mant[0] = (byte) -num;
-                                    ind = isneg;
-                                }
-                            }
-                        }
-                    }
-                    return;
-                } while (false);
-            }/* singledigit */
-
-        /* We work on negative numbers so we handle the most negative number */
-        if (num > 0) {
-            ind = ispos;
-            num = -num;
-        } else
-            ind = isneg;/* negative */// [0 case already handled]
-        // [it is quicker, here, to pre-calculate the length with
-        // one loop, then allocate exactly the right length of byte array,
-        // then re-fill it with another loop]
-        mun = num; // working copy
-        {
-            i = 9;
-            i: for (;; i--) {
-                mun = mun / 10;
-                if (mun == 0)
-                    break i;
-            }
-        }/* i */
-        // i is the position of the leftmost digit placed
-        mant = new byte[10 - i];
-        {
-            i = (10 - i) - 1;
-            i: for (;; i--) {
-                mant[i] = (byte) -(((byte) (num % 10)));
-                num = num / 10;
-                if (num == 0)
-                    break i;
-            }
-        }/* i */
-        return;
-    }
-
-    /**
-     * Constructs a <code>BigDecimal</code> object directly from a <code>long</code>.
-     * <p>
-     * Constructs a <code>BigDecimal</code> which is the exact decimal representation of the 64-bit signed binary
-     * integer parameter. The <code>BigDecimal</code> will contain only decimal digits, prefixed with a leading minus
-     * sign (hyphen) if the parameter is negative. A leading zero will be present only if the parameter is zero.
-     * 
-     * @param num The <code>long</code> to be converted.
-     * @stable ICU 2.0
-     */
-
-    public BigDecimal(long num) {
-        super();
-        long mun;
-        int i = 0;
-        // Not really worth fastpathing commoners in this constructor [also,
-        // we use this to construct the static constants].
-        // This is much faster than: this(String.valueOf(num).toCharArray())
-        /* We work on negative num so we handle the most negative number */
-        if (num > 0) {
-            ind = ispos;
-            num = -num;
-        } else if (num == 0)
-            ind = iszero;
-        else
-            ind = isneg;/* negative */
-        mun = num;
-        {
-            i = 18;
-            i: for (;; i--) {
-                mun = mun / 10;
-                if (mun == 0)
-                    break i;
-            }
-        }/* i */
-        // i is the position of the leftmost digit placed
-        mant = new byte[19 - i];
-        {
-            i = (19 - i) - 1;
-            i: for (;; i--) {
-                mant[i] = (byte) -(((byte) (num % 10)));
-                num = num / 10;
-                if (num == 0)
-                    break i;
-            }
-        }/* i */
-        return;
-    }
-
-    /**
-     * Constructs a <code>BigDecimal</code> object from a <code>String</code>.
-     * <p>
-     * Constructs a <code>BigDecimal</code> from the parameter, which must not be <code>null</code> and must represent a
-     * valid <i>number</i>, as described formally in the documentation referred to {@link BigDecimal above}.
-     * <p>
-     * In summary, numbers in <code>String</code> form must have at least one digit, may have a leading sign, may have a
-     * decimal point, and exponential notation may be used. They follow conventional syntax, and may not contain blanks.
-     * <p>
-     * Some valid strings from which a <code>BigDecimal</code> might be constructed are:
-     * 
-     * <pre>
-     * 
-     * "0" -- Zero "12" -- A whole number "-76" -- A signed whole number "12.70" -- Some decimal places "+0.003" -- Plus
-     * sign is allowed "17." -- The same as 17 ".5" -- The same as 0.5 "4E+9" -- Exponential notation "0.73e-7" --
-     * Exponential notation
-     * 
-     * </pre>
-     * <p>
-     * (Exponential notation means that the number includes an optional sign and a power of ten following an
-     * '</code>E</code>' that indicates how the decimal point will be shifted. Thus the <code>"4E+9"</code> above is
-     * just a short way of writing <code>4000000000</code>, and the <code>"0.73e-7"</code> is short for <code>
-     * 0.000000073</code>.)
-     * <p>
-     * The <code>BigDecimal</code> constructed from the String is in a standard form, with no blanks, as though the
-     * {@link #add(BigDecimal)} method had been used to add zero to the number with unlimited precision. If the string
-     * uses exponential notation (that is, includes an <code>e</code> or an <code>E</code>), then the <code>BigDecimal
-     * </code> number will be expressed in scientific notation (where the power of ten is adjusted so there is a single
-     * non-zero digit to the left of the decimal point); in this case if the number is zero then it will be expressed as
-     * the single digit 0, and if non-zero it will have an exponent unless that exponent would be 0. The exponent must
-     * fit in nine digits both before and after it is expressed in scientific notation.
-     * <p>
-     * Any digits in the parameter must be decimal; that is, <code>Character.digit(c, 10)</code> (where </code>c</code>
-     * is the character in question) would not return -1.
-     * 
-     * @param string The <code>String</code> to be converted.
-     * @throws NumberFormatException If the parameter is not a valid number.
-     * @stable ICU 2.0
-     */
-
-    public BigDecimal(java.lang.String string) {
-        this(string.toCharArray(), 0, string.length());
-        return;
-    }
-
-    /* <sgml> Make a default BigDecimal object for local use. </sgml> */
-
-    private BigDecimal() {
-        super();
-        return;
-    }
-
-    /* ---------------------------------------------------------------- */
-    /* Operator methods [methods which take a context parameter] */
-    /* ---------------------------------------------------------------- */
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
-     * <p>
-     * The same as {@link #abs(MathContext)}, where the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
-     * <p>
-     * The length of the decimal part (the scale) of the result will be <code>this.scale()</code>
-     * 
-     * @return A <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal abs() {
-        return this.abs(plainMC);
-    }
-
-    /**
-     * Returns a <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
-     * <p>
-     * If the current object is zero or positive, then the same result as invoking the {@link #plus(MathContext)} method
-     * with the same parameter is returned. Otherwise, the same result as invoking the {@link #negate(MathContext)}
-     * method with the same parameter is returned.
-     * 
-     * @param set The <code>MathContext</code> arithmetic settings.
-     * @return A <code>BigDecimal</code> whose value is the absolute value of this <code>BigDecimal</code>.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal abs(com.ibm.icu.math.MathContext set) {
-        if (this.ind == isneg)
-            return this.negate(set);
-        return this.plus(set);
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose value is <code>this+rhs</code>, using fixed point arithmetic.
-     * <p>
-     * The same as {@link #add(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
-     * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
-     * <p>
-     * The length of the decimal part (the scale) of the result will be the maximum of the scales of the two operands.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the addition.
-     * @return A <code>BigDecimal</code> whose value is <code>this+rhs</code>, using fixed point arithmetic.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs) {
-        return this.add(rhs, plainMC);
-    }
-
-    /**
-     * Returns a <code>BigDecimal</code> whose value is <code>this+rhs</code>.
-     * <p>
-     * Implements the addition (<b><code>+</code></b>) operator (as defined in the decimal documentation, see
-     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the addition.
-     * @param set The <code>MathContext</code> arithmetic settings.
-     * @return A <code>BigDecimal</code> whose value is <code>this+rhs</code>.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal add(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
-        com.ibm.icu.math.BigDecimal lhs;
-        int reqdig;
-        com.ibm.icu.math.BigDecimal res;
-        byte usel[];
-        int usellen;
-        byte user[];
-        int userlen;
-        int newlen = 0;
-        int tlen = 0;
-        int mult = 0;
-        byte t[] = null;
-        int ia = 0;
-        int ib = 0;
-        int ea = 0;
-        int eb = 0;
-        byte ca = 0;
-        byte cb = 0;
-        /* determine requested digits and form */
-        if (set.lostDigits)
-            checkdigits(rhs, set.digits);
-        lhs = this; // name for clarity and proxy
-
-        /* Quick exit for add floating 0 */
-        // plus() will optimize to return same object if possible
-        if (lhs.ind == 0)
-            if (set.form != com.ibm.icu.math.MathContext.PLAIN)
-                return rhs.plus(set);
-        if (rhs.ind == 0)
-            if (set.form != com.ibm.icu.math.MathContext.PLAIN)
-                return lhs.plus(set);
-
-        /* Prepare numbers (round, unless unlimited precision) */
-        reqdig = set.digits; // local copy (heavily used)
-        if (reqdig > 0) {
-            if (lhs.mant.length > reqdig)
-                lhs = clone(lhs).round(set);
-            if (rhs.mant.length > reqdig)
-                rhs = clone(rhs).round(set);
-            // [we could reuse the new LHS for result in this case]
-        }
-
-        res = new com.ibm.icu.math.BigDecimal(); // build result here
-
-        /*
-         * Now see how much we have to pad or truncate lhs or rhs in order to align the numbers. If one number is much
-         * larger than the other, then the smaller cannot affect the answer [but we may still need to pad with up to
-         * DIGITS trailing zeros].
-         */
-        // Note sign may be 0 if digits (reqdig) is 0
-        // usel and user will be the byte arrays passed to the adder; we'll
-        // use them on all paths except quick exits
-        usel = lhs.mant;
-        usellen = lhs.mant.length;
-        user = rhs.mant;
-        userlen = rhs.mant.length;
-        {
-            do {/* select */
-                if (lhs.exp == rhs.exp) {/* no padding needed */
-                    // This is the most common, and fastest, path
-                    res.exp = lhs.exp;
-                } else if (lhs.exp > rhs.exp) { // need to pad lhs and/or truncate rhs
-                    newlen = (usellen + lhs.exp) - rhs.exp;
-                    /*
-                     * If, after pad, lhs would be longer than rhs by digits+1 or more (and digits>0) then rhs cannot
-                     * affect answer, so we only need to pad up to a length of DIGITS+1.
-                     */
-                    if (newlen >= ((userlen + reqdig) + 1))
-                        if (reqdig > 0) {
-                            // LHS is sufficient
-                            res.mant = usel;
-                            res.exp = lhs.exp;
-                            res.ind = lhs.ind;
-                            if (usellen < reqdig) { // need 0 padding
-                                res.mant = extend(lhs.mant, reqdig);
-                                res.exp = res.exp - ((reqdig - usellen));
-                            }
-                            return res.finish(set, false);
-                        }
-                    // RHS may affect result
-                    res.exp = rhs.exp; // expected final exponent
-                    if (newlen > (reqdig + 1))
-                        if (reqdig > 0) {
-                            // LHS will be max; RHS truncated
-                            tlen = (newlen - reqdig) - 1; // truncation length
-                            userlen = userlen - tlen;
-                            res.exp = res.exp + tlen;
-                            newlen = reqdig + 1;
-                        }
-                    if (newlen > usellen)
-                        usellen = newlen; // need to pad LHS
-                } else { // need to pad rhs and/or truncate lhs
-                    newlen = (userlen + rhs.exp) - lhs.exp;
-                    if (newlen >= ((usellen + reqdig) + 1))
-                        if (reqdig > 0) {
-                            // RHS is sufficient
-                            res.mant = user;
-                            res.exp = rhs.exp;
-                            res.ind = rhs.ind;
-                            if (userlen < reqdig) { // need 0 padding
-                                res.mant = extend(rhs.mant, reqdig);
-                                res.exp = res.exp - ((reqdig - userlen));
-                            }
-                            return res.finish(set, false);
-                        }
-                    // LHS may affect result
-                    res.exp = lhs.exp; // expected final exponent
-                    if (newlen > (reqdig + 1))
-                        if (reqdig > 0) {
-                            // RHS will be max; LHS truncated
-                            tlen = (newlen - reqdig) - 1; // truncation length
-                            usellen = usellen - tlen;
-                            res.exp = res.exp + tlen;
-                            newlen = reqdig + 1;
-                        }
-                    if (newlen > userlen)
-                        userlen = newlen; // need to pad RHS
-                }
-            } while (false);
-        }/* padder */
-
-        /* OK, we have aligned mantissas. Now add or subtract. */
-        // 1998.06.27 Sign may now be 0 [e.g., 0.000] .. treat as positive
-        // 1999.05.27 Allow for 00 on lhs [is not larger than 2 on rhs]
-        // 1999.07.10 Allow for 00 on rhs [is not larger than 2 on rhs]
-        if (lhs.ind == iszero)
-            res.ind = ispos;
-        else
-            res.ind = lhs.ind; // likely sign, all paths
-        if (((lhs.ind == isneg) ? 1 : 0) == ((rhs.ind == isneg) ? 1 : 0)) // same sign, 0 non-negative
-            mult = 1;
-        else {
-            do { // different signs, so subtraction is needed
-                mult = -1; // will cause subtract
-                /*
-                 * Before we can subtract we must determine which is the larger, as our add/subtract routine only
-                 * handles non-negative results so we may need to swap the operands.
-                 */
-                {
-                    do {/* select */
-                        if (rhs.ind == iszero) {
-                            // original A bigger
-                        } else if ((usellen < userlen) | (lhs.ind == iszero)) { // original B bigger
-                            t = usel;
-                            usel = user;
-                            user = t; // swap
-                            tlen = usellen;
-                            usellen = userlen;
-                            userlen = tlen; // ..
-                            res.ind = (byte) -res.ind; // and set sign
-                        } else if (usellen > userlen) {
-                            // original A bigger
-                        } else {
-                            {/* logical lengths the same */// need compare
-                                /* may still need to swap: compare the strings */
-                                ia = 0;
-                                ib = 0;
-                                ea = usel.length - 1;
-                                eb = user.length - 1;
-                                {
-                                    compare: for (;;) {
-                                        if (ia <= ea)
-                                            ca = usel[ia];
-                                        else {
-                                            if (ib > eb) {/* identical */
-                                                if (set.form != com.ibm.icu.math.MathContext.PLAIN)
-                                                    return ZERO;
-                                                // [if PLAIN we must do the subtract, in case of 0.000 results]
-                                                break compare;
-                                            }
-                                            ca = (byte) 0;
-                                        }
-                                        if (ib <= eb)
-                                            cb = user[ib];
-                                        else
-                                            cb = (byte) 0;
-                                        if (ca != cb) {
-                                            if (ca < cb) {/* swap needed */
-                                                t = usel;
-                                                usel = user;
-                                                user = t; // swap
-                                                tlen = usellen;
-                                                usellen = userlen;
-                                                userlen = tlen; // ..
-                                                res.ind = (byte) -res.ind;
-                                            }
-                                            break compare;
-                                        }
-                                        /* mantissas the same, so far */
-                                        ia++;
-                                        ib++;
-                                    }
-                                }/* compare */
-                            } // lengths the same
-                        }
-                    } while (false);
-                }/* swaptest */
-            } while (false);
-        }/* signdiff */
-
-        /* here, A is > B if subtracting */
-        // add [A+B*1] or subtract [A+(B*-1)]
-        res.mant = byteaddsub(usel, usellen, user, userlen, mult, false);
-        // [reuse possible only after chop; accounting makes not worthwhile]
-
-        // Finish() rounds before stripping leading 0's, then sets form, etc.
-        return res.finish(set, false);
-    }
-
-    /**
-     * Compares this <code>BigDecimal</code> to another, using unlimited precision.
-     * <p>
-     * The same as {@link #compareTo(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
-     * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
-     * @return An <code>int</code> whose value is -1, 0, or 1 as <code>this</code> is numerically less than, equal to,
-     *         or greater than <code>rhs</code>.
-     * @stable ICU 2.0
-     */
-
-    public int compareTo(com.ibm.icu.math.BigDecimal rhs) {
-        return this.compareTo(rhs, plainMC);
-    }
-
-    /**
-     * Compares this <code>BigDecimal</code> to another.
-     * <p>
-     * Implements numeric comparison, (as defined in the decimal documentation, see {@link BigDecimal class header}),
-     * and returns a result of type <code>int</code>.
-     * <p>
-     * The result will be:
-     * <table cellpadding=2>
-     * <tr>
-     * <td align=right><b>-1</b></td> <td>if the current object is less than the first parameter</td>
-     * </tr>
-     * <tr>
-     * <td align=right><b>0</b></td> <td>if the current object is equal to the first parameter</td>
-     * </tr>
-     * <tr>
-     * <td align=right><b>1</b></td> <td>if the current object is greater than the first parameter.</td>
-     * </tr>
-     * </table>
-     * <p>
-     * A {@link #compareTo(BigDecimal)} method is also provided.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
-     * @param set The <code>MathContext</code> arithmetic settings.
-     * @return An <code>int</code> whose value is -1, 0, or 1 as <code>this</code> is numerically less than, equal to,
-     *         or greater than <code>rhs</code>.
-     * @stable ICU 2.0
-     */
-
-    public int compareTo(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
-        int thislength = 0;
-        int i = 0;
-        com.ibm.icu.math.BigDecimal newrhs;
-        // rhs=null will raise NullPointerException, as per Comparable interface
-        if (set.lostDigits)
-            checkdigits(rhs, set.digits);
-        // [add will recheck in slowpath cases .. but would report -rhs]
-        if ((this.ind == rhs.ind) & (this.exp == rhs.exp)) {
-            /* sign & exponent the same [very common] */
-            thislength = this.mant.length;
-            if (thislength < rhs.mant.length)
-                return (byte) -this.ind;
-            if (thislength > rhs.mant.length)
-                return this.ind;
-            /*
-             * lengths are the same; we can do a straight mantissa compare unless maybe rounding [rounding is very
-             * unusual]
-             */
-            if ((thislength <= set.digits) | (set.digits == 0)) {
-                {
-                    int $6 = thislength;
-                    i = 0;
-                    for (; $6 > 0; $6--, i++) {
-                        if (this.mant[i] < rhs.mant[i])
-                            return (byte) -this.ind;
-                        if (this.mant[i] > rhs.mant[i])
-                            return this.ind;
-                    }
-                }/* i */
-                return 0; // identical
-            }
-            /* drop through for full comparison */
-        } else {
-            /* More fastpaths possible */
-            if (this.ind < rhs.ind)
-                return -1;
-            if (this.ind > rhs.ind)
-                return 1;
-        }
-        /* carry out a subtract to make the comparison */
-        newrhs = clone(rhs); // safe copy
-        newrhs.ind = (byte) -newrhs.ind; // prepare to subtract
-        return this.add(newrhs, set).ind; // add, and return sign of result
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic.
-     * <p>
-     * The same as {@link #divide(BigDecimal, int)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
-     * rounding mode is {@link MathContext#ROUND_HALF_UP}.
-     * 
-     * The length of the decimal part (the scale) of the result will be the same as the scale of the current object, if
-     * the latter were formatted without exponential notation.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
-     * @return A plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic.
-     * @throws ArithmeticException If <code>rhs</code> is zero.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs) {
-        return this.dodivide('D', rhs, plainMC, -1);
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and a
-     * rounding mode.
-     * <p>
-     * The same as {@link #divide(BigDecimal, int, int)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
-     * second parameter is <code>this.scale()</code>, and the third is <code>round</code>.
-     * <p>
-     * The length of the decimal part (the scale) of the result will therefore be the same as the scale of the current
-     * object, if the latter were formatted without exponential notation.
-     * <p>
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
-     * @param round The <code>int</code> rounding mode to be used for the division (see the {@link MathContext} class).
-     * @return A plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and
-     *         the specified rounding mode.
-     * @throws IllegalArgumentException if <code>round</code> is not a valid rounding mode.
-     * @throws ArithmeticException if <code>rhs</code> is zero.
-     * @throws ArithmeticException if <code>round</code> is {@link MathContext#ROUND_UNNECESSARY} and <code>this.scale()</code> is insufficient to represent the result exactly.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, int round) {
-        com.ibm.icu.math.MathContext set;
-        set = new com.ibm.icu.math.MathContext(0, com.ibm.icu.math.MathContext.PLAIN, false, round); // [checks round,
-                                                                                                     // too]
-        return this.dodivide('D', rhs, set, -1); // take scale from LHS
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and a
-     * given scale and rounding mode.
-     * <p>
-     * The same as {@link #divide(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
-     * <code>new MathContext(0, MathContext.PLAIN, false, round)</code>, except that the length of the decimal part (the
-     * scale) to be used for the result is explicit rather than being taken from <code>this</code>.
-     * <p>
-     * The length of the decimal part (the scale) of the result will be the same as the scale of the current object, if
-     * the latter were formatted without exponential notation.
-     * <p>
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
-     * @param scale The <code>int</code> scale to be used for the result.
-     * @param round The <code>int</code> rounding mode to be used for the division (see the {@link MathContext} class).
-     * @return A plain <code>BigDecimal</code> whose value is <code>this/rhs</code>, using fixed point arithmetic and
-     *         the specified rounding mode.
-     * @throws IllegalArgumentException if <code>round</code> is not a valid rounding mode.
-     * @throws ArithmeticException if <code>rhs</code> is zero.
-     * @throws ArithmeticException if <code>scale</code> is negative.
-     * @throws ArithmeticException if <code>round</code> is {@link MathContext#ROUND_UNNECESSARY} and <code>scale</code> is insufficient
-     *             to represent the result exactly.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, int scale, int round) {
-        com.ibm.icu.math.MathContext set;
-        if (scale < 0)
-            throw new java.lang.ArithmeticException("Negative scale:" + " " + scale);
-        set = new com.ibm.icu.math.MathContext(0, com.ibm.icu.math.MathContext.PLAIN, false, round); // [checks round]
-        return this.dodivide('D', rhs, set, scale);
-    }
-
-    /**
-     * Returns a <code>BigDecimal</code> whose value is <code>this/rhs</code>.
-     * <p>
-     * Implements the division (<b><code>/</code></b>) operator (as defined in the decimal documentation, see
-     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the division.
-     * @param set The <code>MathContext</code> arithmetic settings.
-     * @return A <code>BigDecimal</code> whose value is <code>this/rhs</code>.
-     * @throws ArithmeticException if <code>rhs</code> is zero.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal divide(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
-        return this.dodivide('D', rhs, set, -1);
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
-     * <p>
-     * The same as {@link #divideInteger(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs
-     * </code>, and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the integer division.
-     * @return A <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
-     * @throws ArithmeticException if <code>rhs</code> is zero.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs) {
-        // scale 0 to drop .000 when plain
-        return this.dodivide('I', rhs, plainMC, 0);
-    }
-
-    /**
-     * Returns a <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
-     * <p>
-     * Implements the integer division operator (as defined in the decimal documentation, see {@link BigDecimal class
-     * header}), and returns the result as a <code>BigDecimal</code> object.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the integer division.
-     * @param set The <code>MathContext</code> arithmetic settings.
-     * @return A <code>BigDecimal</code> whose value is the integer part of <code>this/rhs</code>.
-     * @throws ArithmeticException if <code>rhs</code> is zero.
-     * @throws ArithmeticException if the result will not fit in the number of digits specified for the context.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal divideInteger(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
-        // scale 0 to drop .000 when plain
-        return this.dodivide('I', rhs, set, 0);
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
-     * <p>
-     * The same as {@link #max(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
-     * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
-     * @return A <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs) {
-        return this.max(rhs, plainMC);
-    }
-
-    /**
-     * Returns a <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
-     * <p>
-     * Returns the larger of the current object and the first parameter.
-     * <p>
-     * If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return <code>1
-     * </code> or <code>0</code>, then the result of calling the {@link #plus(MathContext)} method on the current object
-     * (using the same <code>MathContext</code> parameter) is returned. Otherwise, the result of calling the
-     * {@link #plus(MathContext)} method on the first parameter object (using the same <code>MathContext</code>
-     * parameter) is returned.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
-     * @param set The <code>MathContext</code> arithmetic settings.
-     * @return A <code>BigDecimal</code> whose value is the maximum of <code>this</code> and <code>rhs</code>.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal max(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
-        if ((this.compareTo(rhs, set)) >= 0)
-            return this.plus(set);
-        else
-            return rhs.plus(set);
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
-     * <p>
-     * The same as {@link #min(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
-     * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
-     * @return A <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs) {
-        return this.min(rhs, plainMC);
-    }
-
-    /**
-     * Returns a <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
-     * <p>
-     * Returns the smaller of the current object and the first parameter.
-     * <p>
-     * If calling the {@link #compareTo(BigDecimal, MathContext)} method with the same parameters would return <code>-1
-     * </code> or <code>0</code>, then the result of calling the {@link #plus(MathContext)} method on the current object
-     * (using the same <code>MathContext</code> parameter) is returned. Otherwise, the result of calling the
-     * {@link #plus(MathContext)} method on the first parameter object (using the same <code>MathContext</code>
-     * parameter) is returned.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the comparison.
-     * @param set The <code>MathContext</code> arithmetic settings.
-     * @return A <code>BigDecimal</code> whose value is the minimum of <code>this</code> and <code>rhs</code>.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal min(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
-        if ((this.compareTo(rhs, set)) <= 0)
-            return this.plus(set);
-        else
-            return rhs.plus(set);
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose value is <code>this*rhs</code>, using fixed point arithmetic.
-     * <p>
-     * The same as {@link #add(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
-     * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
-     * <p>
-     * The length of the decimal part (the scale) of the result will be the sum of the scales of the operands, if they
-     * were formatted without exponential notation.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the multiplication.
-     * @return A <code>BigDecimal</code> whose value is <code>this*rhs</code>, using fixed point arithmetic.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs) {
-        return this.multiply(rhs, plainMC);
-    }
-
-    /**
-     * Returns a <code>BigDecimal</code> whose value is <code>this*rhs</code>.
-     * <p>
-     * Implements the multiplication (<b><code> </code></b>) operator (as defined in the decimal documentation, see
-     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the multiplication.
-     * @param set The <code>MathContext</code> arithmetic settings.
-     * @return A <code>BigDecimal</code> whose value is <code>this*rhs</code>.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal multiply(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
-        com.ibm.icu.math.BigDecimal lhs;
-        int padding;
-        int reqdig;
-        byte multer[] = null;
-        byte multand[] = null;
-        int multandlen;
-        int acclen = 0;
-        com.ibm.icu.math.BigDecimal res;
-        byte acc[];
-        int n = 0;
-        byte mult = 0;
-        if (set.lostDigits)
-            checkdigits(rhs, set.digits);
-        lhs = this; // name for clarity and proxy
-
-        /* Prepare numbers (truncate, unless unlimited precision) */
-        padding = 0; // trailing 0's to add
-        reqdig = set.digits; // local copy
-        if (reqdig > 0) {
-            if (lhs.mant.length > reqdig)
-                lhs = clone(lhs).round(set);
-            if (rhs.mant.length > reqdig)
-                rhs = clone(rhs).round(set);
-            // [we could reuse the new LHS for result in this case]
-        } else {/* unlimited */
-            // fixed point arithmetic will want every trailing 0; we add these
-            // after the calculation rather than before, for speed.
-            if (lhs.exp > 0)
-                padding = padding + lhs.exp;
-            if (rhs.exp > 0)
-                padding = padding + rhs.exp;
-        }
-
-        // For best speed, as in DMSRCN, we use the shorter number as the
-        // multiplier and the longer as the multiplicand.
-        // 1999.12.22: We used to special case when the result would fit in
-        // a long, but with Java 1.3 this gave no advantage.
-        if (lhs.mant.length < rhs.mant.length) {
-            multer = lhs.mant;
-            multand = rhs.mant;
-        } else {
-            multer = rhs.mant;
-            multand = lhs.mant;
-        }
-
-        /* Calculate how long result byte array will be */
-        multandlen = (multer.length + multand.length) - 1; // effective length
-        // optimize for 75% of the cases where a carry is expected...
-        if ((multer[0] * multand[0]) > 9)
-            acclen = multandlen + 1;
-        else
-            acclen = multandlen;
-
-        /* Now the main long multiplication loop */
-        res = new com.ibm.icu.math.BigDecimal(); // where we'll build result
-        acc = new byte[acclen]; // accumulator, all zeros
-        // 1998.07.01: calculate from left to right so that accumulator goes
-        // to likely final length on first addition; this avoids a one-digit
-        // extension (and object allocation) each time around the loop.
-        // Initial number therefore has virtual zeros added to right.
-        {
-            int $7 = multer.length;
-            n = 0;
-            for (; $7 > 0; $7--, n++) {
-                mult = multer[n];
-                if (mult != 0) { // [optimization]
-                    // accumulate [accumulator is reusable array]
-                    acc = byteaddsub(acc, acc.length, multand, multandlen, mult, true);
-                }
-                // divide multiplicand by 10 for next digit to right
-                multandlen--; // 'virtual length'
-            }
-        }/* n */
-
-        res.ind = (byte) (lhs.ind * rhs.ind); // final sign
-        res.exp = (lhs.exp + rhs.exp) - padding; // final exponent
-        // [overflow is checked by finish]
-
-        /* add trailing zeros to the result, if necessary */
-        if (padding == 0)
-            res.mant = acc;
-        else
-            res.mant = extend(acc, acc.length + padding); // add trailing 0s
-        return res.finish(set, false);
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose value is <code>-this</code>.
-     * <p>
-     * The same as {@link #negate(MathContext)}, where the context is <code>new MathContext(0, MathContext.PLAIN)</code>
-     * .
-     * <p>
-     * The length of the decimal part (the scale) of the result will be be <code>this.scale()</code>
-     * 
-     * 
-     * @return A <code>BigDecimal</code> whose value is <code>-this</code>.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal negate() {
-        return this.negate(plainMC);
-    }
-
-    /**
-     * Returns a <code>BigDecimal</code> whose value is <code>-this</code>.
-     * <p>
-     * Implements the negation (Prefix <b><code>-</code></b>) operator (as defined in the decimal documentation, see
-     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
-     * 
-     * @param set The <code>MathContext</code> arithmetic settings.
-     * @return A <code>BigDecimal</code> whose value is <code>-this</code>.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal negate(com.ibm.icu.math.MathContext set) {
-        com.ibm.icu.math.BigDecimal res;
-        // Originally called minus(), changed to matched Java precedents
-        // This simply clones, flips the sign, and possibly rounds
-        if (set.lostDigits)
-            checkdigits((com.ibm.icu.math.BigDecimal) null, set.digits);
-        res = clone(this); // safe copy
-        res.ind = (byte) -res.ind;
-        return res.finish(set, false);
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose value is <code>+this</code>. Note that <code>this</code> is not
-     * necessarily a plain <code>BigDecimal</code>, but the result will always be.
-     * <p>
-     * The same as {@link #plus(MathContext)}, where the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
-     * <p>
-     * The length of the decimal part (the scale) of the result will be be <code>this.scale()</code>
-     * 
-     * @return A <code>BigDecimal</code> whose value is <code>+this</code>.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal plus() {
-        return this.plus(plainMC);
-    }
-
-    /**
-     * Returns a <code>BigDecimal</code> whose value is <code>+this</code>.
-     * <p>
-     * Implements the plus (Prefix <b><code>+</code></b>) operator (as defined in the decimal documentation, see
-     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
-     * <p>
-     * This method is useful for rounding or otherwise applying a context to a decimal value.
-     * 
-     * @param set The <code>MathContext</code> arithmetic settings.
-     * @return A <code>BigDecimal</code> whose value is <code>+this</code>.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal plus(com.ibm.icu.math.MathContext set) {
-        // This clones and forces the result to the new settings
-        // May return same object
-        if (set.lostDigits)
-            checkdigits((com.ibm.icu.math.BigDecimal) null, set.digits);
-        // Optimization: returns same object for some common cases
-        if (set.form == com.ibm.icu.math.MathContext.PLAIN)
-            if (this.form == com.ibm.icu.math.MathContext.PLAIN) {
-                if (this.mant.length <= set.digits)
-                    return this;
-                if (set.digits == 0)
-                    return this;
-            }
-        return clone(this).finish(set, false);
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose value is <code>this**rhs</code>, using fixed point arithmetic.
-     * <p>
-     * The same as {@link #pow(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>, and the
-     * context is <code>new MathContext(0, MathContext.PLAIN)</code>.
-     * <p>
-     * The parameter is the power to which the <code>this</code> will be raised; it must be in the range 0 through
-     * 999999999, and must have a decimal part of zero. Note that these restrictions may be removed in the future, so
-     * they should not be used as a test for a whole number.
-     * <p>
-     * In addition, the power must not be negative, as no <code>MathContext</code> is used and so the result would then
-     * always be 0.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the operation (the power).
-     * @return A <code>BigDecimal</code> whose value is <code>this**rhs</code>, using fixed point arithmetic.
-     * @throws ArithmeticException if <code>rhs</code> is out of range or is not a whole number.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs) {
-        return this.pow(rhs, plainMC);
-    }
-
-    // The name for this method is inherited from the precedent set by the
-    // BigInteger and Math classes.
-
-    /**
-     * Returns a <code>BigDecimal</code> whose value is <code>this**rhs</code>.
-     * <p>
-     * Implements the power (<b><code> </code></b>) operator (as defined in the decimal documentation, see
-     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
-     * <p>
-     * The first parameter is the power to which the <code>this</code> will be raised; it must be in the range
-     * -999999999 through 999999999, and must have a decimal part of zero. Note that these restrictions may be removed
-     * in the future, so they should not be used as a test for a whole number.
-     * <p>
-     * If the <code>digits</code> setting of the <code>MathContext</code> parameter is 0, the power must be zero or
-     * positive.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the operation (the power).
-     * @param set The <code>MathContext</code> arithmetic settings.
-     * @return A <code>BigDecimal</code> whose value is <code>this**rhs</code>.
-     * @throws ArithmeticException if <code>rhs</code> is out of range or is not a whole number.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal pow(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
-        int n;
-        com.ibm.icu.math.BigDecimal lhs;
-        int reqdig;
-        int workdigits = 0;
-        int L = 0;
-        com.ibm.icu.math.MathContext workset;
-        com.ibm.icu.math.BigDecimal res;
-        boolean seenbit;
-        int i = 0;
-        if (set.lostDigits)
-            checkdigits(rhs, set.digits);
-        n = rhs.intcheck(MinArg, MaxArg); // check RHS by the rules
-        lhs = this; // clarified name
-
-        reqdig = set.digits; // local copy (heavily used)
-        if (reqdig == 0) {
-            if (rhs.ind == isneg)
-                throw new java.lang.ArithmeticException("Negative power:" + " " + rhs.toString());
-            workdigits = 0;
-        } else {/* non-0 digits */
-            if ((rhs.mant.length + rhs.exp) > reqdig)
-                throw new java.lang.ArithmeticException("Too many digits:" + " " + rhs.toString());
-
-            /* Round the lhs to DIGITS if need be */
-            if (lhs.mant.length > reqdig)
-                lhs = clone(lhs).round(set);
-
-            /* L for precision calculation [see ANSI X3.274-1996] */
-            L = rhs.mant.length + rhs.exp; // length without decimal zeros/exp
-            workdigits = (reqdig + L) + 1; // calculate the working DIGITS
-        }
-
-        /* Create a copy of set for working settings */
-        // Note: no need to check for lostDigits again.
-        // 1999.07.17 Note: this construction must follow RHS check
-        workset = new com.ibm.icu.math.MathContext(workdigits, set.form, false, set.roundingMode);
-
-        res = ONE; // accumulator
-        if (n == 0)
-            return res; // x**0 == 1
-        if (n < 0)
-            n = -n; // [rhs.ind records the sign]
-        seenbit = false; // set once we've seen a 1-bit
-        {
-            i = 1;
-            i: for (;; i++) { // for each bit [top bit ignored]
-                n = n + n; // shift left 1 bit
-                if (n < 0) { // top bit is set
-                    seenbit = true; // OK, we're off
-                    res = res.multiply(lhs, workset); // acc=acc*x
-                }
-                if (i == 31)
-                    break i; // that was the last bit
-                if ((!seenbit))
-                    continue i; // we don't have to square 1
-                res = res.multiply(res, workset); // acc=acc*acc [square]
-            }
-        }/* i */// 32 bits
-        if (rhs.ind < 0) // was a **-n [hence digits>0]
-            res = ONE.divide(res, workset); // .. so acc=1/acc
-        return res.finish(set, true); // round and strip [original digits]
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose value is the remainder of <code>this/rhs</code>, using fixed point
-     * arithmetic.
-     * <p>
-     * The same as {@link #remainder(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
-     * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
-     * <p>
-     * This is not the modulo operator -- the result may be negative.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the remainder operation.
-     * @return A <code>BigDecimal</code> whose value is the remainder of <code>this/rhs</code>, using fixed point
-     *         arithmetic.
-     * @throws ArithmeticException if <code>rhs</code> is zero.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs) {
-        return this.dodivide('R', rhs, plainMC, -1);
-    }
-
-    /**
-     * Returns a <code>BigDecimal</code> whose value is the remainder of <code>this/rhs</code>.
-     * <p>
-     * Implements the remainder operator (as defined in the decimal documentation, see {@link BigDecimal class header}),
-     * and returns the result as a <code>BigDecimal</code> object.
-     * <p>
-     * This is not the modulo operator -- the result may be negative.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the remainder operation.
-     * @param set The <code>MathContext</code> arithmetic settings.
-     * @return A <code>BigDecimal</code> whose value is the remainder of <code>this+rhs</code>.
-     * @throws ArithmeticException if <code>rhs</code> is zero.
-     * @throws ArithmeticException  if the integer part of the result will not fit in the number of digits specified for the context.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal remainder(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
-        return this.dodivide('R', rhs, set, -1);
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose value is <code>this-rhs</code>, using fixed point arithmetic.
-     * <p>
-     * The same as {@link #subtract(BigDecimal, MathContext)}, where the <code>BigDecimal</code> is <code>rhs</code>,
-     * and the context is <code>new MathContext(0, MathContext.PLAIN)</code>.
-     * <p>
-     * The length of the decimal part (the scale) of the result will be the maximum of the scales of the two operands.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the subtraction.
-     * @return A <code>BigDecimal</code> whose value is <code>this-rhs</code>, using fixed point arithmetic.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs) {
-        return this.subtract(rhs, plainMC);
-    }
-
-    /**
-     * Returns a <code>BigDecimal</code> whose value is <code>this-rhs</code>.
-     * <p>
-     * Implements the subtraction (<b><code>-</code></b>) operator (as defined in the decimal documentation, see
-     * {@link BigDecimal class header}), and returns the result as a <code>BigDecimal</code> object.
-     * 
-     * @param rhs The <code>BigDecimal</code> for the right hand side of the subtraction.
-     * @param set The <code>MathContext</code> arithmetic settings.
-     * @return A <code>BigDecimal</code> whose value is <code>this-rhs</code>.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal subtract(com.ibm.icu.math.BigDecimal rhs, com.ibm.icu.math.MathContext set) {
-        com.ibm.icu.math.BigDecimal newrhs;
-        if (set.lostDigits)
-            checkdigits(rhs, set.digits);
-        // [add will recheck .. but would report -rhs]
-        /* carry out the subtraction */
-        // we could fastpath -0, but it is too rare.
-        newrhs = clone(rhs); // safe copy
-        newrhs.ind = (byte) -newrhs.ind; // prepare to subtract
-        return this.add(newrhs, set); // arithmetic
-    }
-
-    /* ---------------------------------------------------------------- */
-    /* Other methods */
-    /* ---------------------------------------------------------------- */
-
-    /**
-     * Converts this <code>BigDecimal</code> to a <code>byte</code>. If the <code>BigDecimal</code> has a non-zero
-     * decimal part or is out of the possible range for a <code>byte</code> (8-bit signed integer) result then an <code>
-     * ArithmeticException</code> is thrown.
-     * 
-     * @return A <code>byte</code> equal in value to <code>this</code>.
-     * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in a <code>byte</code>.
-     * @stable ICU 2.0
-     */
-
-    public byte byteValueExact() {
-        int num;
-        num = this.intValueExact(); // will check decimal part too
-        if ((num > 127) | (num < (-128)))
-            throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
-        return (byte) num;
-    }
-
-    /**
-     * Converts this <code>BigDecimal</code> to a <code>double</code>. If the <code>BigDecimal</code> is out of the
-     * possible range for a <code>double</code> (64-bit signed floating point) result then an <code>ArithmeticException
-     * </code> is thrown.
-     * <p>
-     * The double produced is identical to result of expressing the <code>BigDecimal</code> as a <code>String</code> and
-     * then converting it using the <code>Double(String)</code> constructor; this can result in values of <code>
-     * Double.NEGATIVE_INFINITY</code> or <code>Double.POSITIVE_INFINITY</code>.
-     * 
-     * @return A <code>double</code> corresponding to <code>this</code>.
-     * @stable ICU 2.0
-     */
-
-    public double doubleValue() {
-        // We go via a String [as does BigDecimal in JDK 1.2]
-        // Next line could possibly raise NumberFormatException
-        return java.lang.Double.valueOf(this.toString()).doubleValue();
-    }
-
-    /**
-     * Compares this <code>BigDecimal</code> with <code>rhs</code> for equality.
-     * <p>
-     * If the parameter is <code>null</code>, or is not an instance of the BigDecimal type, or is not exactly equal to
-     * the current <code>BigDecimal</code> object, then <i>false</i> is returned. Otherwise, <i>true</i> is returned.
-     * <p>
-     * "Exactly equal", here, means that the <code>String</code> representations of the <code>BigDecimal</code> numbers
-     * are identical (they have the same characters in the same sequence).
-     * <p>
-     * The {@link #compareTo(BigDecimal, MathContext)} method should be used for more general comparisons.
-     * 
-     * @param obj The <code>Object</code> for the right hand side of the comparison.
-     * @return A <code>boolean</code> whose value <i>true</i> if and only if the operands have identical string
-     *         representations.
-     * @throws ClassCastException if <code>rhs</code> cannot be cast to a <code>BigDecimal</code> object.
-     * @stable ICU 2.0
-     * @see #compareTo(BigDecimal)
-     * @see #compareTo(BigDecimal, MathContext)
-     */
-
-    public boolean equals(java.lang.Object obj) {
-        com.ibm.icu.math.BigDecimal rhs;
-        int i = 0;
-        char lca[] = null;
-        char rca[] = null;
-        // We are equal iff toString of both are exactly the same
-        if (obj == null)
-            return false; // not equal
-        if ((!(((obj instanceof com.ibm.icu.math.BigDecimal)))))
-            return false; // not a decimal
-        rhs = (com.ibm.icu.math.BigDecimal) obj; // cast; we know it will work
-        if (this.ind != rhs.ind)
-            return false; // different signs never match
-        if (((this.mant.length == rhs.mant.length) & (this.exp == rhs.exp)) & (this.form == rhs.form))
-
-        { // mantissas say all
-            // here with equal-length byte arrays to compare
-            {
-                int $8 = this.mant.length;
-                i = 0;
-                for (; $8 > 0; $8--, i++) {
-                    if (this.mant[i] != rhs.mant[i])
-                        return false;
-                }
-            }/* i */
-        } else { // need proper layout
-            lca = this.layout(); // layout to character array
-            rca = rhs.layout();
-            if (lca.length != rca.length)
-                return false; // mismatch
-            // here with equal-length character arrays to compare
-            {
-                int $9 = lca.length;
-                i = 0;
-                for (; $9 > 0; $9--, i++) {
-                    if (lca[i] != rca[i])
-                        return false;
-                }
-            }/* i */
-        }
-        return true; // arrays have identical content
-    }
-
-    /**
-     * Converts this <code>BigDecimal</code> to a <code>float</code>. If the <code>BigDecimal</code> is out of the
-     * possible range for a <code>float</code> (32-bit signed floating point) result then an <code>ArithmeticException
-     * </code> is thrown.
-     * <p>
-     * The float produced is identical to result of expressing the <code>BigDecimal</code> as a <code>String</code> and
-     * then converting it using the <code>Float(String)</code> constructor; this can result in values of <code>
-     * Float.NEGATIVE_INFINITY</code> or <code>Float.POSITIVE_INFINITY</code>.
-     * 
-     * @return A <code>float</code> corresponding to <code>this</code>.
-     * @stable ICU 2.0
-     */
-
-    public float floatValue() {
-        return java.lang.Float.valueOf(this.toString()).floatValue();
-    }
-
-    /**
-     * Returns the <code>String</code> representation of this <code>BigDecimal</code>, modified by layout parameters.
-     * <p>
-     * <i>This method is provided as a primitive for use by more sophisticated classes, such as <code>DecimalFormat
-     * </code>, that can apply locale-sensitive editing of the result. The level of formatting that it provides is a
-     * necessary part of the BigDecimal class as it is sensitive to and must follow the calculation and rounding rules
-     * for BigDecimal arithmetic. However, if the function is provided elsewhere, it may be removed from this class.
-     * </i>
-     * <p>
-     * The parameters, for both forms of the <code>format</code> method are all of type <code>int</code>. A value of -1
-     * for any parameter indicates that the default action or value for that parameter should be used.
-     * <p>
-     * The parameters, <code>before</code> and <code>after</code>, specify the number of characters to be used for the
-     * integer part and decimal part of the result respectively. Exponential notation is not used. If either parameter
-     * is -1 (which indicates the default action), the number of characters used will be exactly as many as are needed
-     * for that part.
-     * <p>
-     * <code>before</code> must be a positive number; if it is larger than is needed to contain the integer part, that
-     * part is padded on the left with blanks to the requested length. If <code>before</code> is not large enough to
-     * contain the integer part of the number (including the sign, for negative numbers) an exception is thrown.
-     * <p>
-     * <code>after</code> must be a non-negative number; if it is not the same size as the decimal part of the number,
-     * the number will be rounded (or extended with zeros) to fit. Specifying 0 for <code>after</code> will cause the
-     * number to be rounded to an integer (that is, it will have no decimal part or decimal point). The rounding method
-     * will be the default, <code>MathContext.ROUND_HALF_UP</code>.
-     * <p>
-     * Other rounding methods, and the use of exponential notation, can be selected by using
-     * {@link #format(int,int,int,int,int,int)}. Using the two-parameter form of the method has exactly the same effect
-     * as using the six-parameter form with the final four parameters all being -1.
-     * 
-     * @param before The <code>int</code> specifying the number of places before the decimal point. Use -1 for 'as many as are needed'.
-     * @param after The <code>int</code> specifying the number of places after the decimal point. Use -1 for 'as many as are needed'.
-     * @return A <code>String</code> representing this <code>BigDecimal</code>, laid out according to the specified parameters
-     * @throws ArithmeticException if the number cannot be laid out as requested.
-     * @throws IllegalArgumentException if a parameter is out of range.
-     * @stable ICU 2.0
-     * @see #toString
-     * @see #toCharArray
-     */
-
-    public java.lang.String format(int before, int after) {
-        return format(before, after, -1, -1, com.ibm.icu.math.MathContext.SCIENTIFIC, ROUND_HALF_UP);
-    }
-
-    /**
-     * Returns the <code>String</code> representation of this <code>BigDecimal</code>, modified by layout parameters and
-     * allowing exponential notation.
-     * <p>
-     * <i>This method is provided as a primitive for use by more sophisticated classes, such as <code>DecimalFormat
-     * </code>, that can apply locale-sensitive editing of the result. The level of formatting that it provides is a
-     * necessary part of the BigDecimal class as it is sensitive to and must follow the calculation and rounding rules
-     * for BigDecimal arithmetic. However, if the function is provided elsewhere, it may be removed from this class.
-     * </i>
-     * <p>
-     * The parameters are all of type <code>int</code>. A value of -1 for any parameter indicates that the default
-     * action or value for that parameter should be used.
-     * <p>
-     * The first two parameters (<code>before</code> and <code>after</code>) specify the number of characters to be used
-     * for the integer part and decimal part of the result respectively, as defined for {@link #format(int,int)}. If
-     * either of these is -1 (which indicates the default action), the number of characters used will be exactly as many
-     * as are needed for that part.
-     * <p>
-     * The remaining parameters control the use of exponential notation and rounding. Three (<code>explaces</code>,
-     * <code>exdigits</code>, and <code>exform</code>) control the exponent part of the result. As before, the default
-     * action for any of these parameters may be selected by using the value -1.
-     * <p>
-     * <code>explaces</code> must be a positive number; it sets the number of places (digits after the sign of the
-     * exponent) to be used for any exponent part, the default (when <code>explaces</code> is -1) being to use as many
-     * as are needed. If <code>explaces</code> is not -1, space is always reserved for an exponent; if one is not needed
-     * (for example, if the exponent will be 0) then <code>explaces</code>+2 blanks are appended to the result. <!--
-     * (This preserves vertical alignment of similarly formatted numbers in a monospace font.) --> If <code>explaces
-     * </code> is not -1 and is not large enough to contain the exponent, an exception is thrown.
-     * <p>
-     * <code>exdigits</code> sets the trigger point for use of exponential notation. If, before any rounding, the number
-     * of places needed before the decimal point exceeds <code>exdigits</code>, or if the absolute value of the result
-     * is less than <code>0.000001</code>, then exponential form will be used, provided that <code>exdigits</code> was
-     * specified. When <code>exdigits</code> is -1, exponential notation will never be used. If 0 is specified for
-     * <code>exdigits</code>, exponential notation is always used unless the exponent would be 0.
-     * <p>
-     * <code>exform</code> sets the form for exponential notation (if needed). It may be either
-     * {@link MathContext#SCIENTIFIC} or {@link MathContext#ENGINEERING}. If the latter, engineering, form is requested,
-     * up to three digits (plus sign, if negative) may be needed for the integer part of the result (<code>before</code>
-     * ). Otherwise, only one digit (plus sign, if negative) is needed.
-     * <p>
-     * Finally, the sixth argument, <code>exround</code>, selects the rounding algorithm to be used, and must be one of
-     * the values indicated by a public constant in the {@link MathContext} class whose name starts with <code>ROUND_
-     * </code>. The default (<code>ROUND_HALF_UP</code>) may also be selected by using the value -1, as before.
-     * <p>
-     * The special value <code>MathContext.ROUND_UNNECESSARY</code> may be used to detect whether non-zero digits are
-     * discarded -- if <code>exround</code> has this value than if non-zero digits would be discarded (rounded) during
-     * formatting then an <code>ArithmeticException</code> is thrown.
-     * 
-     * @param before The <code>int</code> specifying the number of places before the decimal point. Use -1 for 'as many as
-     *            are needed'.
-     * @param after The <code>int</code> specifying the number of places after the decimal point. Use -1 for 'as many as
-     *            are needed'.
-     * @param explaces The <code>int</code> specifying the number of places to be used for any exponent. Use -1 for 'as many
-     *            as are needed'.
-     * @param exdigits The <code>int</code> specifying the trigger (digits before the decimal point) which if exceeded causes
-     *            exponential notation to be used. Use 0 to force exponential notation. Use -1 to force plain notation
-     *            (no exponential notation).
-     * @param exformint The <code>int</code> specifying the form of exponential notation to be used (
-     *            {@link MathContext#SCIENTIFIC} or {@link MathContext#ENGINEERING}).
-     * @param exround The <code>int</code> specifying the rounding mode to use. Use -1 for the default,
-     *            {@link MathContext#ROUND_HALF_UP}.
-     * @return A <code>String</code> representing this <code>BigDecimal</code>, laid out according to the specified
-     *         parameters
-     * @throws ArithmeticException if the number cannot be laid out as requested.
-     * @throws IllegalArgumentException if a parameter is out of range.
-     * @see #toString
-     * @see #toCharArray
-     * @stable ICU 2.0
-     */
-
-    public java.lang.String format(int before, int after, int explaces, int exdigits, int exformint, int exround) {
-        com.ibm.icu.math.BigDecimal num;
-        int mag = 0;
-        int thisafter = 0;
-        int lead = 0;
-        byte newmant[] = null;
-        int chop = 0;
-        int need = 0;
-        int oldexp = 0;
-        char a[];
-        int p = 0;
-        char newa[] = null;
-        int i = 0;
-        int places = 0;
-
-        /* Check arguments */
-        if ((before < (-1)) | (before == 0))
-            badarg("format", 1, java.lang.String.valueOf(before));
-        if (after < (-1))
-            badarg("format", 2, java.lang.String.valueOf(after));
-        if ((explaces < (-1)) | (explaces == 0))
-            badarg("format", 3, java.lang.String.valueOf(explaces));
-        if (exdigits < (-1))
-            badarg("format", 4, java.lang.String.valueOf(explaces));
-        {/* select */
-            if (exformint == com.ibm.icu.math.MathContext.SCIENTIFIC) {
-            } else if (exformint == com.ibm.icu.math.MathContext.ENGINEERING) {
-            } else if (exformint == (-1))
-                exformint = com.ibm.icu.math.MathContext.SCIENTIFIC;
-            // note PLAIN isn't allowed
-            else {
-                badarg("format", 5, java.lang.String.valueOf(exformint));
-            }
-        }
-        // checking the rounding mode is done by trying to construct a
-        // MathContext object with that mode; it will fail if bad
-        if (exround != ROUND_HALF_UP) {
-            try { // if non-default...
-                if (exround == (-1))
-                    exround = ROUND_HALF_UP;
-                else
-                    new com.ibm.icu.math.MathContext(9, com.ibm.icu.math.MathContext.SCIENTIFIC, false, exround);
-            } catch (java.lang.IllegalArgumentException $10) {
-                badarg("format", 6, java.lang.String.valueOf(exround));
-            }
-        }
-
-        num = clone(this); // make private copy
-
-        /*
-         * Here: num is BigDecimal to format before is places before point [>0] after is places after point [>=0]
-         * explaces is exponent places [>0] exdigits is exponent digits [>=0] exformint is exponent form [one of two]
-         * exround is rounding mode [one of eight] 'before' through 'exdigits' are -1 if not specified
-         */
-
-        /* determine form */
-        {
-            do {/* select */
-                if (exdigits == (-1))
-                    num.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
-                else if (num.ind == iszero)
-                    num.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
-                else {
-                    // determine whether triggers
-                    mag = num.exp + num.mant.length;
-                    if (mag > exdigits)
-                        num.form = (byte) exformint;
-                    else if (mag < (-5))
-                        num.form = (byte) exformint;
-                    else
-                        num.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
-                }
-            } while (false);
-        }/* setform */
-
-        /*
-         * If 'after' was specified then we may need to adjust the mantissa. This is a little tricky, as we must conform
-         * to the rules of exponential layout if necessary (e.g., we cannot end up with 10.0 if scientific).
-         */
-        if (after >= 0) {
-            setafter: for (;;) {
-                // calculate the current after-length
-                {/* select */
-                    if (num.form == com.ibm.icu.math.MathContext.PLAIN)
-                        thisafter = -num.exp; // has decimal part
-                    else if (num.form == com.ibm.icu.math.MathContext.SCIENTIFIC)
-                        thisafter = num.mant.length - 1;
-                    else { // engineering
-                        lead = (((num.exp + num.mant.length) - 1)) % 3; // exponent to use
-                        if (lead < 0)
-                            lead = 3 + lead; // negative exponent case
-                        lead++; // number of leading digits
-                        if (lead >= num.mant.length)
-                            thisafter = 0;
-                        else
-                            thisafter = num.mant.length - lead;
-                    }
-                }
-                if (thisafter == after)
-                    break setafter; // we're in luck
-                if (thisafter < after) { // need added trailing zeros
-                    // [thisafter can be negative]
-                    newmant = extend(num.mant, (num.mant.length + after) - thisafter);
-                    num.mant = newmant;
-                    num.exp = num.exp - ((after - thisafter)); // adjust exponent
-                    if (num.exp < MinExp)
-                        throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + num.exp);
-                    break setafter;
-                }
-                // We have too many digits after the decimal point; this could
-                // cause a carry, which could change the mantissa...
-                // Watch out for implied leading zeros in PLAIN case
-                chop = thisafter - after; // digits to lop [is >0]
-                if (chop > num.mant.length) { // all digits go, no chance of carry
-                    // carry on with zero
-                    num.mant = ZERO.mant;
-                    num.ind = iszero;
-                    num.exp = 0;
-                    continue setafter; // recheck: we may need trailing zeros
-                }
-                // we have a digit to inspect from existing mantissa
-                // round the number as required
-                need = num.mant.length - chop; // digits to end up with [may be 0]
-                oldexp = num.exp; // save old exponent
-                num.round(need, exround);
-                // if the exponent grew by more than the digits we chopped, then
-                // we must have had a carry, so will need to recheck the layout
-                if ((num.exp - oldexp) == chop)
-                    break setafter; // number did not have carry
-                // mantissa got extended .. so go around and check again
-            }
-        }/* setafter */
-
-        a = num.layout(); // lay out, with exponent if required, etc.
-
-        /* Here we have laid-out number in 'a' */
-        // now apply 'before' and 'explaces' as needed
-        if (before > 0) {
-            // look for '.' or 'E'
-            {
-                int $11 = a.length;
-                p = 0;
-                p: for (; $11 > 0; $11--, p++) {
-                    if (a[p] == '.')
-                        break p;
-                    if (a[p] == 'E')
-                        break p;
-                }
-            }/* p */
-            // p is now offset of '.', 'E', or character after end of array
-            // that is, the current length of before part
-            if (p > before)
-                badarg("format", 1, java.lang.String.valueOf(before)); // won't fit
-            if (p < before) { // need leading blanks
-                newa = new char[(a.length + before) - p];
-                {
-                    int $12 = before - p;
-                    i = 0;
-                    for (; $12 > 0; $12--, i++) {
-                        newa[i] = ' ';
-                    }
-                }/* i */
-                java.lang.System.arraycopy((java.lang.Object) a, 0, (java.lang.Object) newa, i, a.length);
-                a = newa;
-            }
-            // [if p=before then it's just the right length]
-        }
-
-        if (explaces > 0) {
-            // look for 'E' [cannot be at offset 0]
-            {
-                int $13 = a.length - 1;
-                p = a.length - 1;
-                p: for (; $13 > 0; $13--, p--) {
-                    if (a[p] == 'E')
-                        break p;
-                }
-            }/* p */
-            // p is now offset of 'E', or 0
-            if (p == 0) { // no E part; add trailing blanks
-                newa = new char[(a.length + explaces) + 2];
-                java.lang.System.arraycopy((java.lang.Object) a, 0, (java.lang.Object) newa, 0, a.length);
-                {
-                    int $14 = explaces + 2;
-                    i = a.length;
-                    for (; $14 > 0; $14--, i++) {
-                        newa[i] = ' ';
-                    }
-                }/* i */
-                a = newa;
-            } else {/* found E */// may need to insert zeros
-                places = (a.length - p) - 2; // number so far
-                if (places > explaces)
-                    badarg("format", 3, java.lang.String.valueOf(explaces));
-                if (places < explaces) { // need to insert zeros
-                    newa = new char[(a.length + explaces) - places];
-                    java.lang.System.arraycopy((java.lang.Object) a, 0, (java.lang.Object) newa, 0, p + 2); // through E
-                                                                                                            // and sign
-                    {
-                        int $15 = explaces - places;
-                        i = p + 2;
-                        for (; $15 > 0; $15--, i++) {
-                            newa[i] = '0';
-                        }
-                    }/* i */
-                    java.lang.System.arraycopy((java.lang.Object) a, p + 2, (java.lang.Object) newa, i, places); // remainder
-                                                                                                                 // of
-                                                                                                                 // exponent
-                    a = newa;
-                }
-                // [if places=explaces then it's just the right length]
-            }
-        }
-        return new java.lang.String(a);
-    }
-
-    /**
-     * Returns the hashcode for this <code>BigDecimal</code>. This hashcode is suitable for use by the <code>
-     * java.util.Hashtable</code> class.
-     * <p>
-     * Note that two <code>BigDecimal</code> objects are only guaranteed to produce the same hashcode if they are
-     * exactly equal (that is, the <code>String</code> representations of the <code>BigDecimal</code> numbers are
-     * identical -- they have the same characters in the same sequence).
-     * 
-     * @return An <code>int</code> that is the hashcode for <code>this</code>.
-     * @stable ICU 2.0
-     */
-
-    public int hashCode() {
-        // Maybe calculate ourselves, later. If so, note that there can be
-        // more than one internal representation for a given toString() result.
-        return this.toString().hashCode();
-    }
-
-    /**
-     * Converts this <code>BigDecimal</code> to an <code>int</code>. If the <code>BigDecimal</code> has a non-zero
-     * decimal part it is discarded. If the <code>BigDecimal</code> is out of the possible range for an <code>int</code>
-     * (32-bit signed integer) result then only the low-order 32 bits are used. (That is, the number may be
-     * <i>decapitated</i>.) To avoid unexpected errors when these conditions occur, use the {@link #intValueExact}
-     * method.
-     * 
-     * @return An <code>int</code> converted from <code>this</code>, truncated and decapitated if necessary.
-     * @stable ICU 2.0
-     */
-
-    public int intValue() {
-        return toBigInteger().intValue();
-    }
-
-    /**
-     * Converts this <code>BigDecimal</code> to an <code>int</code>. If the <code>BigDecimal</code> has a non-zero
-     * decimal part or is out of the possible range for an <code>int</code> (32-bit signed integer) result then an
-     * <code>ArithmeticException</code> is thrown.
-     * 
-     * @return An <code>int</code> equal in value to <code>this</code>.
-     * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in an <code>int</code>.
-     * @stable ICU 2.0
-     */
-
-    public int intValueExact() {
-        int lodigit;
-        int useexp = 0;
-        int result;
-        int i = 0;
-        int topdig = 0;
-        // This does not use longValueExact() as the latter can be much
-        // slower.
-        // intcheck (from pow) relies on this to check decimal part
-        if (ind == iszero)
-            return 0; // easy, and quite common
-        /* test and drop any trailing decimal part */
-        lodigit = mant.length - 1;
-        if (exp < 0) {
-            lodigit = lodigit + exp; // reduces by -(-exp)
-            /* all decimal places must be 0 */
-            if ((!(allzero(mant, lodigit + 1))))
-                throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString());
-            if (lodigit < 0)
-                return 0; // -1<this<1
-            useexp = 0;
-        } else {/* >=0 */
-            if ((exp + lodigit) > 9) // early exit
-                throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
-            useexp = exp;
-        }
-        /* convert the mantissa to binary, inline for speed */
-        result = 0;
-        {
-            int $16 = lodigit + useexp;
-            i = 0;
-            for (; i <= $16; i++) {
-                result = result * 10;
-                if (i <= lodigit)
-                    result = result + mant[i];
-            }
-        }/* i */
-
-        /* Now, if the risky length, check for overflow */
-        if ((lodigit + useexp) == 9) {
-            // note we cannot just test for -ve result, as overflow can move a
-            // zero into the top bit [consider 5555555555]
-            topdig = result / 1000000000; // get top digit, preserving sign
-            if (topdig != mant[0]) { // digit must match and be positive
-                // except in the special case ...
-                if (result == java.lang.Integer.MIN_VALUE) // looks like the special
-                    if (ind == isneg) // really was negative
-                        if (mant[0] == 2)
-                            return result; // really had top digit 2
-                throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
-            }
-        }
-
-        /* Looks good */
-        if (ind == ispos)
-            return result;
-        return -result;
-    }
-
-    /**
-     * Converts this <code>BigDecimal</code> to a <code>long</code>. If the <code>BigDecimal</code> has a non-zero
-     * decimal part it is discarded. If the <code>BigDecimal</code> is out of the possible range for a <code>long</code>
-     * (64-bit signed integer) result then only the low-order 64 bits are used. (That is, the number may be
-     * <i>decapitated</i>.) To avoid unexpected errors when these conditions occur, use the {@link #longValueExact}
-     * method.
-     * 
-     * @return A <code>long</code> converted from <code>this</code>, truncated and decapitated if necessary.
-     * @stable ICU 2.0
-     */
-
-    public long longValue() {
-        return toBigInteger().longValue();
-    }
-
-    /**
-     * Converts this <code>BigDecimal</code> to a <code>long</code>. If the <code>BigDecimal</code> has a non-zero
-     * decimal part or is out of the possible range for a <code>long</code> (64-bit signed integer) result then an
-     * <code>ArithmeticException</code> is thrown.
-     * 
-     * @return A <code>long</code> equal in value to <code>this</code>.
-     * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in a <code>long</code>.
-     * @stable ICU 2.0
-     */
-
-    public long longValueExact() {
-        int lodigit;
-        int cstart = 0;
-        int useexp = 0;
-        long result;
-        int i = 0;
-        long topdig = 0;
-        // Identical to intValueExact except for result=long, and exp>=20 test
-        if (ind == 0)
-            return 0; // easy, and quite common
-        lodigit = mant.length - 1; // last included digit
-        if (exp < 0) {
-            lodigit = lodigit + exp; // -(-exp)
-            /* all decimal places must be 0 */
-            if (lodigit < 0)
-                cstart = 0;
-            else
-                cstart = lodigit + 1;
-            if ((!(allzero(mant, cstart))))
-                throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString());
-            if (lodigit < 0)
-                return 0; // -1<this<1
-            useexp = 0;
-        } else {/* >=0 */
-            if ((exp + mant.length) > 18) // early exit
-                throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
-            useexp = exp;
-        }
-
-        /* convert the mantissa to binary, inline for speed */
-        // note that we could safely use the 'test for wrap to negative'
-        // algorithm here, but instead we parallel the intValueExact
-        // algorithm for ease of checking and maintenance.
-        result = (long) 0;
-        {
-            int $17 = lodigit + useexp;
-            i = 0;
-            for (; i <= $17; i++) {
-                result = result * 10;
-                if (i <= lodigit)
-                    result = result + mant[i];
-            }
-        }/* i */
-
-        /* Now, if the risky length, check for overflow */
-        if ((lodigit + useexp) == 18) {
-            topdig = result / 1000000000000000000L; // get top digit, preserving sign
-            if (topdig != mant[0]) { // digit must match and be positive
-                // except in the special case ...
-                if (result == java.lang.Long.MIN_VALUE) // looks like the special
-                    if (ind == isneg) // really was negative
-                        if (mant[0] == 9)
-                            return result; // really had top digit 9
-                throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
-            }
-        }
-
-        /* Looks good */
-        if (ind == ispos)
-            return result;
-        return -result;
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose decimal point has been moved to the left by a specified number of
-     * positions. The parameter, <code>n</code>, specifies the number of positions to move the decimal point. That is,
-     * if <code>n</code> is 0 or positive, the number returned is given by:
-     * <p>
-     * <code> this.multiply(TEN.pow(new BigDecimal(-n))) </code>
-     * <p>
-     * <code>n</code> may be negative, in which case the method returns the same result as <code>movePointRight(-n)
-     * </code>.
-     * 
-     * @param n The <code>int</code> specifying the number of places to move the decimal point leftwards.
-     * @return A <code>BigDecimal</code> derived from <code>this</code>, with the decimal point moved <code>n</code>
-     *         places to the left.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal movePointLeft(int n) {
-        com.ibm.icu.math.BigDecimal res;
-        // very little point in optimizing for shift of 0
-        res = clone(this);
-        res.exp = res.exp - n;
-        return res.finish(plainMC, false); // finish sets form and checks exponent
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> whose decimal point has been moved to the right by a specified number of
-     * positions. The parameter, <code>n</code>, specifies the number of positions to move the decimal point. That is,
-     * if <code>n</code> is 0 or positive, the number returned is given by:
-     * <p>
-     * <code> this.multiply(TEN.pow(new BigDecimal(n))) </code>
-     * <p>
-     * <code>n</code> may be negative, in which case the method returns the same result as <code>movePointLeft(-n)
-     * </code>.
-     * 
-     * @param n The <code>int</code> specifying the number of places to move the decimal point rightwards.
-     * @return A <code>BigDecimal</code> derived from <code>this</code>, with the decimal point moved <code>n</code>
-     *         places to the right.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal movePointRight(int n) {
-        com.ibm.icu.math.BigDecimal res;
-        res = clone(this);
-        res.exp = res.exp + n;
-        return res.finish(plainMC, false);
-    }
-
-    /**
-     * Returns the scale of this <code>BigDecimal</code>. Returns a non-negative <code>int</code> which is the scale of
-     * the number. The scale is the number of digits in the decimal part of the number if the number were formatted
-     * without exponential notation.
-     * 
-     * @return An <code>int</code> whose value is the scale of this <code>BigDecimal</code>.
-     * @stable ICU 2.0
-     */
-
-    public int scale() {
-        if (exp >= 0)
-            return 0; // scale can never be negative
-        return -exp;
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> with a given scale.
-     * <p>
-     * If the given scale (which must be zero or positive) is the same as or greater than the length of the decimal part
-     * (the scale) of this <code>BigDecimal</code> then trailing zeros will be added to the decimal part as necessary.
-     * <p>
-     * If the given scale is less than the length of the decimal part (the scale) of this <code>BigDecimal</code> then
-     * trailing digits will be removed, and in this case an <code>ArithmeticException</code> is thrown if any discarded
-     * digits are non-zero.
-     * <p>
-     * The same as {@link #setScale(int, int)}, where the first parameter is the scale, and the second is <code>
-     * MathContext.ROUND_UNNECESSARY</code>.
-     * 
-     * @param scale The <code>int</code> specifying the scale of the resulting <code>BigDecimal</code>.
-     * @return A plain <code>BigDecimal</code> with the given scale.
-     * @throws ArithmeticException if <code>scale</code> is negative.
-     * @throws ArithmeticException if reducing scale would discard non-zero digits.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal setScale(int scale) {
-        return setScale(scale, ROUND_UNNECESSARY);
-    }
-
-    /**
-     * Returns a plain <code>BigDecimal</code> with a given scale.
-     * <p>
-     * If the given scale (which must be zero or positive) is the same as or greater than the length of the decimal part
-     * (the scale) of this <code>BigDecimal</code> then trailing zeros will be added to the decimal part as necessary.
-     * <p>
-     * If the given scale is less than the length of the decimal part (the scale) of this <code>BigDecimal</code> then
-     * trailing digits will be removed, and the rounding mode given by the second parameter is used to determine if the
-     * remaining digits are affected by a carry. In this case, an <code>IllegalArgumentException</code> is thrown if
-     * <code>round</code> is not a valid rounding mode.
-     * <p>
-     * If <code>round</code> is <code>MathContext.ROUND_UNNECESSARY</code>, an <code>ArithmeticException</code> is
-     * thrown if any discarded digits are non-zero.
-     * 
-     * @param scale The <code>int</code> specifying the scale of the resulting <code>BigDecimal</code>.
-     * @param round The <code>int</code> rounding mode to be used for the division (see the {@link MathContext} class).
-     * @return A plain <code>BigDecimal</code> with the given scale.
-     * @throws IllegalArgumentException if <code>round</code> is not a valid rounding mode.
-     * @throws ArithmeticException if <code>scale</code> is negative.
-     * @throws ArithmeticException if <code>round</code> is <code>MathContext.ROUND_UNNECESSARY</code>, and reducing scale would discard
-     *             non-zero digits.
-     * @stable ICU 2.0
-     */
-
-    public com.ibm.icu.math.BigDecimal setScale(int scale, int round) {
-        int ourscale;
-        com.ibm.icu.math.BigDecimal res;
-        int padding = 0;
-        int newlen = 0;
-        // at present this naughtily only checks the round value if it is
-        // needed (used), for speed
-        ourscale = this.scale();
-        if (ourscale == scale) // already correct scale
-            if (this.form == com.ibm.icu.math.MathContext.PLAIN) // .. and form
-                return this;
-        res = clone(this); // need copy
-        if (ourscale <= scale) { // simply zero-padding/changing form
-            // if ourscale is 0 we may have lots of 0s to add
-            if (ourscale == 0)
-                padding = res.exp + scale;
-            else
-                padding = scale - ourscale;
-            res.mant = extend(res.mant, res.mant.length + padding);
-            res.exp = -scale; // as requested
-        } else {/* ourscale>scale: shortening, probably */
-            if (scale < 0)
-                throw new java.lang.ArithmeticException("Negative scale:" + " " + scale);
-            // [round() will raise exception if invalid round]
-            newlen = res.mant.length - ((ourscale - scale)); // [<=0 is OK]
-            res = res.round(newlen, round); // round to required length
-            // This could have shifted left if round (say) 0.9->1[.0]
-            // Repair if so by adding a zero and reducing exponent
-            if (res.exp != -scale) {
-                res.mant = extend(res.mant, res.mant.length + 1);
-                res.exp = res.exp - 1;
-            }
-        }
-        res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; // by definition
-        return res;
-    }
-
-    /**
-     * Converts this <code>BigDecimal</code> to a <code>short</code>. If the <code>BigDecimal</code> has a non-zero
-     * decimal part or is out of the possible range for a <code>short</code> (16-bit signed integer) result then an
-     * <code>ArithmeticException</code> is thrown.
-     * 
-     * @return A <code>short</code> equal in value to <code>this</code>.
-     * @throws ArithmeticException if <code>this</code> has a non-zero decimal part, or will not fit in a <code>short</code>.
-     * @stable ICU 2.0
-     */
-
-    public short shortValueExact() {
-        int num;
-        num = this.intValueExact(); // will check decimal part too
-        if ((num > 32767) | (num < (-32768)))
-            throw new java.lang.ArithmeticException("Conversion overflow:" + " " + this.toString());
-        return (short) num;
-    }
-
-    /**
-     * Returns the sign of this <code>BigDecimal</code>, as an <code>int</code>. This returns the <i>signum</i> function
-     * value that represents the sign of this <code>BigDecimal</code>. That is, -1 if the <code>BigDecimal</code> is
-     * negative, 0 if it is numerically equal to zero, or 1 if it is positive.
-     * 
-     * @return An <code>int</code> which is -1 if the <code>BigDecimal</code> is negative, 0 if it is numerically equal
-     *         to zero, or 1 if it is positive.
-     * @stable ICU 2.0
-     */
-
-    public int signum() {
-        return (int) this.ind; // [note this assumes values for ind.]
-    }
-
-    /**
-     * Converts this <code>BigDecimal</code> to a <code>java.math.BigDecimal</code>.
-     * <p>
-     * This is an exact conversion; the result is the same as if the <code>BigDecimal</code> were formatted as a plain
-     * number without any rounding or exponent and then the <code>java.math.BigDecimal(java.lang.String)</code>
-     * constructor were used to construct the result.
-     * <p>
-     * <i>(Note: this method is provided only in the <code>com.ibm.icu.math</code> version of the BigDecimal class. It
-     * would not be present in a <code>java.math</code> version.)</i>
-     * 
-     * @return The <code>java.math.BigDecimal</code> equal in value to this <code>BigDecimal</code>.
-     * @stable ICU 2.0
-     */
-
-    public java.math.BigDecimal toBigDecimal() {
-        return new java.math.BigDecimal(this.unscaledValue(), this.scale());
-    }
-
-    /**
-     * Converts this <code>BigDecimal</code> to a <code>java.math.BigInteger</code>.
-     * <p>
-     * Any decimal part is truncated (discarded). If an exception is desired should the decimal part be non-zero, use
-     * {@link #toBigIntegerExact()}.
-     * 
-     * @return The <code>java.math.BigInteger</code> equal in value to the integer part of this <code>BigDecimal</code>.
-     * @stable ICU 2.0
-     */
-
-    public java.math.BigInteger toBigInteger() {
-        com.ibm.icu.math.BigDecimal res = null;
-        int newlen = 0;
-        byte newmant[] = null;
-        {/* select */
-            if ((exp >= 0) & (form == com.ibm.icu.math.MathContext.PLAIN))
-                res = this; // can layout simply
-            else if (exp >= 0) {
-                res = clone(this); // safe copy
-                res.form = (byte) com.ibm.icu.math.MathContext.PLAIN; // .. and request PLAIN
-            } else {
-                { // exp<0; scale to be truncated
-                    // we could use divideInteger, but we may as well be quicker
-                    if (-this.exp >= this.mant.length)
-                        res = ZERO; // all blows away
-                    else {
-                        res = clone(this); // safe copy
-                        newlen = res.mant.length + res.exp;
-                        newmant = new byte[newlen]; // [shorter]
-                        java.lang.System.arraycopy((java.lang.Object) res.mant, 0, (java.lang.Object) newmant, 0,
-                                newlen);
-                        res.mant = newmant;
-                        res.form = (byte) com.ibm.icu.math.MathContext.PLAIN;
-                        res.exp = 0;
-                    }
-                }
-            }
-        }
-        return new BigInteger(new java.lang.String(res.layout()));
-    }
-
-    /**
-     * Converts this <code>BigDecimal</code> to a <code>java.math.BigInteger</code>.
-     * <p>
-     * An exception is thrown if the decimal part (if any) is non-zero.
-     * 
-     * @return The <code>java.math.BigInteger</code> equal in value to the integer part of this <code>BigDecimal</code>.
-     * @throws ArithmeticException if <code>this</code> has a non-zero decimal part.
-     * @stable ICU 2.0
-     */
-
-    public java.math.BigInteger toBigIntegerExact() {
-        /* test any trailing decimal part */
-        if (exp < 0) { // possible decimal part
-            /* all decimal places must be 0; note exp<0 */
-            if ((!(allzero(mant, mant.length + exp))))
-                throw new java.lang.ArithmeticException("Decimal part non-zero:" + " " + this.toString());
-        }
-        return toBigInteger();
-    }
-
-    /**
-     * Returns the <code>BigDecimal</code> as a character array. The result of this method is the same as using the
-     * sequence <code>toString().toCharArray()</code>, but avoids creating the intermediate <code>String</code> and
-     * <code>char[]</code> objects.
-     * 
-     * @return The <code>char[]</code> array corresponding to this <code>BigDecimal</code>.
-     * @stable ICU 2.0
-     */
-
-    public char[] toCharArray() {
-        return layout();
-    }
-
-    /**
-     * Returns the <code>BigDecimal</code> as a <code>String</code>. This returns a <code>String</code> that exactly
-     * represents this <code>BigDecimal</code>, as defined in the decimal documentation (see {@link BigDecimal class
-     * header}).
-     * <p>
-     * By definition, using the {@link #BigDecimal(String)} constructor on the result <code>String</code> will create a
-     * <code>BigDecimal</code> that is exactly equal to the original <code>BigDecimal</code>.
-     * 
-     * @return The <code>String</code> exactly corresponding to this <code>BigDecimal</code>.
-     * @see #format(int, int)
-     * @see #format(int, int, int, int, int, int)
-     * @see #toCharArray()
-     * @stable ICU 2.0
-     */
-
-    public java.lang.String toString() {
-        return new java.lang.String(layout());
-    }
-
-    /**
-     * Returns the number as a <code>BigInteger</code> after removing the scale. That is, the number is expressed as a
-     * plain number, any decimal point is then removed (retaining the digits of any decimal part), and the result is
-     * then converted to a <code>BigInteger</code>.
-     * 
-     * @return The <code>java.math.BigInteger</code> equal in value to this <code>BigDecimal</code> multiplied by ten to
-     *         the power of <code>this.scale()</code>.
-     * @stable ICU 2.0
-     */
-
-    public java.math.BigInteger unscaledValue() {
-        com.ibm.icu.math.BigDecimal res = null;
-        if (exp >= 0)
-            res = this;
-        else {
-            res = clone(this); // safe copy
-            res.exp = 0; // drop scale
-        }
-        return res.toBigInteger();
-    }
-
-    /**
-     * Translates a <code>double</code> to a <code>BigDecimal</code>.
-     * <p>
-     * Returns a <code>BigDecimal</code> which is the decimal representation of the 64-bit signed binary floating point
-     * parameter. If the parameter is infinite, or is not a number (NaN), a <code>NumberFormatException</code> is
-     * thrown.
-     * <p>
-     * The number is constructed as though <code>num</code> had been converted to a <code>String</code> using the <code>
-     * Double.toString()</code> method and the {@link #BigDecimal(java.lang.String)} constructor had then been used.
-     * This is typically not an exact conversion.
-     * 
-     * @param dub The <code>double</code> to be translated.
-     * @return The <code>BigDecimal</code> equal in value to <code>dub</code>.
-     * @throws NumberFormatException if the parameter is infinite or not a number.
-     * @stable ICU 2.0
-     */
-
-    public static com.ibm.icu.math.BigDecimal valueOf(double dub) {
-        // Reminder: a zero double returns '0.0', so we cannot fastpath to
-        // use the constant ZERO. This might be important enough to justify
-        // a factory approach, a cache, or a few private constants, later.
-        return new com.ibm.icu.math.BigDecimal((new java.lang.Double(dub)).toString());
-    }
-
-    /**
-     * Translates a <code>long</code> to a <code>BigDecimal</code>. That is, returns a plain <code>BigDecimal</code>
-     * whose value is equal to the given <code>long</code>.
-     * 
-     * @param lint The <code>long</code> to be translated.
-     * @return The <code>BigDecimal</code> equal in value to <code>lint</code>.
-     * @stable ICU 2.0
-     */
-
-    public static com.ibm.icu.math.BigDecimal valueOf(long lint) {
-        return valueOf(lint, 0);
-    }
-
-    /**
-     * Translates a <code>long</code> to a <code>BigDecimal</code> with a given scale. That is, returns a plain <code>
-     * BigDecimal</code> whose unscaled value is equal to the given <code>long</code>, adjusted by the second parameter,
-     * <code>scale</code>.
-     * <p>
-     * The result is given by:
-     * <p>
-     * <code> (new BigDecimal(lint)).divide(TEN.pow(new BigDecimal(scale))) </code>
-     * <p>
-     * A <code>NumberFormatException</code> is thrown if <code>scale</code> is negative.
-     * 
-     * @param lint The <code>long</code> to be translated.
-     * @param scale The <code>int</code> scale to be applied.
-     * @return The <code>BigDecimal</code> equal in value to <code>lint</code>.
-     * @throws NumberFormatException if the scale is negative.
-     * @stable ICU 2.0
-     */
-
-    public static com.ibm.icu.math.BigDecimal valueOf(long lint, int scale) {
-        com.ibm.icu.math.BigDecimal res = null;
-        {/* select */
-            if (lint == 0)
-                res = ZERO;
-            else if (lint == 1)
-                res = ONE;
-            else if (lint == 10)
-                res = TEN;
-            else {
-                res = new com.ibm.icu.math.BigDecimal(lint);
-            }
-        }
-        if (scale == 0)
-            return res;
-        if (scale < 0)
-            throw new java.lang.NumberFormatException("Negative scale:" + " " + scale);
-        res = clone(res); // safe copy [do not mutate]
-        res.exp = -scale; // exponent is -scale
-        return res;
-    }
-
-    /* ---------------------------------------------------------------- */
-    /* Private methods */
-    /* ---------------------------------------------------------------- */
-
-    /*
-     * <sgml> Return char array value of a BigDecimal (conversion from BigDecimal to laid-out canonical char array).
-     * <p>The mantissa will either already have been rounded (following an operation) or will be of length appropriate
-     * (in the case of construction from an int, for example). <p>We must not alter the mantissa, here. <p>'form'
-     * describes whether we are to use exponential notation (and if so, which), or if we are to lay out as a plain/pure
-     * numeric. </sgml>
-     */
-
-    private char[] layout() {
-        char cmant[];
-        int i = 0;
-        StringBuilder sb = null;
-        int euse = 0;
-        int sig = 0;
-        char csign = 0;
-        char rec[] = null;
-        int needsign;
-        int mag;
-        int len = 0;
-        cmant = new char[mant.length]; // copy byte[] to a char[]
-        {
-            int $18 = mant.length;
-            i = 0;
-            for (; $18 > 0; $18--, i++) {
-                cmant[i] = (char) (mant[i] + ((int) ('0')));
-            }
-        }/* i */
-
-        if (form != com.ibm.icu.math.MathContext.PLAIN) {/* exponential notation needed */
-            sb = new StringBuilder(cmant.length + 15); // -x.xxxE+999999999
-            if (ind == isneg)
-                sb.append('-');
-            euse = (exp + cmant.length) - 1; // exponent to use
-            /* setup sig=significant digits and copy to result */
-            if (form == com.ibm.icu.math.MathContext.SCIENTIFIC) { // [default]
-                sb.append(cmant[0]); // significant character
-                if (cmant.length > 1) // have decimal part
-                    sb.append('.').append(cmant, 1, cmant.length - 1);
-            } else {
-                do {
-                    sig = euse % 3; // common
-                    if (sig < 0)
-                        sig = 3 + sig; // negative exponent
-                    euse = euse - sig;
-                    sig++;
-                    if (sig >= cmant.length) { // zero padding may be needed
-                        sb.append(cmant, 0, cmant.length);
-                        {
-                            int $19 = sig - cmant.length;
-                            for (; $19 > 0; $19--) {
-                                sb.append('0');
-                            }
-                        }
-                    } else { // decimal point needed
-                        sb.append(cmant, 0, sig).append('.').append(cmant, sig, cmant.length - sig);
-                    }
-                } while (false);
-            }/* engineering */
-            if (euse != 0) {
-                if (euse < 0) {
-                    csign = '-';
-                    euse = -euse;
-                } else
-                    csign = '+';
-                sb.append('E').append(csign).append(euse);
-            }
-            rec = new char[sb.length()];
-            int srcEnd = sb.length();
-            if (0 != srcEnd) {
-                sb.getChars(0, srcEnd, rec, 0);
-            }
-            return rec;
-        }
-
-        /* Here for non-exponential (plain) notation */
-        if (exp == 0) {/* easy */
-            if (ind >= 0)
-                return cmant; // non-negative integer
-            rec = new char[cmant.length + 1];
-            rec[0] = '-';
-            java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, 1, cmant.length);
-            return rec;
-        }
-
-        /* Need a '.' and/or some zeros */
-        needsign = (ind == isneg) ? 1 : 0; // space for sign? 0 or 1
-
-        /*
-         * MAG is the position of the point in the mantissa (index of the character it follows)
-         */
-        mag = exp + cmant.length;
-
-        if (mag < 1) {/* 0.00xxxx form */
-            len = (needsign + 2) - exp; // needsign+2+(-mag)+cmant.length
-            rec = new char[len];
-            if (needsign != 0)
-                rec[0] = '-';
-            rec[needsign] = '0';
-            rec[needsign + 1] = '.';
-            {
-                int $20 = -mag;
-                i = needsign + 2;
-                for (; $20 > 0; $20--, i++) { // maybe none
-                    rec[i] = '0';
-                }
-            }/* i */
-            java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, (needsign + 2) - mag,
-                    cmant.length);
-            return rec;
-        }
-
-        if (mag > cmant.length) {/* xxxx0000 form */
-            len = needsign + mag;
-            rec = new char[len];
-            if (needsign != 0)
-                rec[0] = '-';
-            java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, needsign, cmant.length);
-            {
-                int $21 = mag - cmant.length;
-                i = needsign + cmant.length;
-                for (; $21 > 0; $21--, i++) { // never 0
-                    rec[i] = '0';
-                }
-            }/* i */
-            return rec;
-        }
-
-        /* decimal point is in the middle of the mantissa */
-        len = (needsign + 1) + cmant.length;
-        rec = new char[len];
-        if (needsign != 0)
-            rec[0] = '-';
-        java.lang.System.arraycopy((java.lang.Object) cmant, 0, (java.lang.Object) rec, needsign, mag);
-        rec[needsign + mag] = '.';
-        java.lang.System.arraycopy((java.lang.Object) cmant, mag, (java.lang.Object) rec, (needsign + mag) + 1,
-                cmant.length - mag);
-        return rec;
-    }
-
-    /*
-     * <sgml> Checks a BigDecimal argument to ensure it's a true integer in a given range. <p>If OK, returns it as an
-     * int. </sgml>
-     */
-    // [currently only used by pow]
-    private int intcheck(int min, int max) {
-        int i;
-        i = this.intValueExact(); // [checks for non-0 decimal part]
-        // Use same message as though intValueExact failed due to size
-        if ((i < min) | (i > max))
-            throw new java.lang.ArithmeticException("Conversion overflow:" + " " + i);
-        return i;
-    }
-
-    /* <sgml> Carry out division operations. </sgml> */
-    /*
-     * Arg1 is operation code: D=divide, I=integer divide, R=remainder Arg2 is the rhs. Arg3 is the context. Arg4 is
-     * explicit scale iff code='D' or 'I' (-1 if none).
-     * 
-     * Underlying algorithm (complications for Remainder function and scaled division are omitted for clarity):
-     * 
-     * Test for x/0 and then 0/x Exp =Exp1 - Exp2 Exp =Exp +len(var1) -len(var2) Sign=Sign1 Sign2 Pad accumulator (Var1)
-     * to double-length with 0's (pad1) Pad Var2 to same length as Var1 B2B=1st two digits of var2, +1 to allow for
-     * roundup have=0 Do until (have=digits+1 OR residue=0) if exp<0 then if integer divide/residue then leave
-     * this_digit=0 Do forever compare numbers if <0 then leave inner_loop if =0 then (- quick exit without subtract -)
-     * do this_digit=this_digit+1; output this_digit leave outer_loop; end Compare lengths of numbers (mantissae): If
-     * same then CA=first_digit_of_Var1 else CA=first_two_digits_of_Var1 mult=ca10/b2b -- Good and safe guess at divisor
-     * if mult=0 then mult=1 this_digit=this_digit+mult subtract end inner_loop if have\=0 | this_digit\=0 then do
-     * output this_digit have=have+1; end var2=var2/10 exp=exp-1 end outer_loop exp=exp+1 -- set the proper exponent if
-     * have=0 then generate answer=0 Return to FINISHED Result defined by MATHV1
-     * 
-     * For extended commentary, see DMSRCN.
-     */
-
-    private com.ibm.icu.math.BigDecimal dodivide(char code, com.ibm.icu.math.BigDecimal rhs,
-            com.ibm.icu.math.MathContext set, int scale) {
-        com.ibm.icu.math.BigDecimal lhs;
-        int reqdig;
-        int newexp;
-        com.ibm.icu.math.BigDecimal res;
-        int newlen;
-        byte var1[];
-        int var1len;
-        byte var2[];
-        int var2len;
-        int b2b;
-        int have;
-        int thisdigit = 0;
-        int i = 0;
-        byte v2 = 0;
-        int ba = 0;
-        int mult = 0;
-        int start = 0;
-        int padding = 0;
-        int d = 0;
-        byte newvar1[] = null;
-        byte lasthave = 0;
-        int actdig = 0;
-        byte newmant[] = null;
-
-        if (set.lostDigits)
-            checkdigits(rhs, set.digits);
-        lhs = this; // name for clarity
-
-        // [note we must have checked lostDigits before the following checks]
-        if (rhs.ind == 0)
-            throw new java.lang.ArithmeticException("Divide by 0"); // includes 0/0
-        if (lhs.ind == 0) { // 0/x => 0 [possibly with .0s]
-            if (set.form != com.ibm.icu.math.MathContext.PLAIN)
-                return ZERO;
-            if (scale == (-1))
-                return lhs;
-            return lhs.setScale(scale);
-        }
-
-        /* Prepare numbers according to BigDecimal rules */
-        reqdig = set.digits; // local copy (heavily used)
-        if (reqdig > 0) {
-            if (lhs.mant.length > reqdig)
-                lhs = clone(lhs).round(set);
-            if (rhs.mant.length > reqdig)
-                rhs = clone(rhs).round(set);
-        } else {/* scaled divide */
-            if (scale == (-1))
-                scale = lhs.scale();
-            // set reqdig to be at least large enough for the computation
-            reqdig = lhs.mant.length; // base length
-            // next line handles both positive lhs.exp and also scale mismatch
-            if (scale != -lhs.exp)
-                reqdig = (reqdig + scale) + lhs.exp;
-            reqdig = (reqdig - ((rhs.mant.length - 1))) - rhs.exp; // reduce by RHS effect
-            if (reqdig < lhs.mant.length)
-                reqdig = lhs.mant.length; // clamp
-            if (reqdig < rhs.mant.length)
-                reqdig = rhs.mant.length; // ..
-        }
-
-        /* precalculate exponent */
-        newexp = ((lhs.exp - rhs.exp) + lhs.mant.length) - rhs.mant.length;
-        /* If new exponent -ve, then some quick exits are possible */
-        if (newexp < 0)
-            if (code != 'D') {
-                if (code == 'I')
-                    return ZERO; // easy - no integer part
-                /* Must be 'R'; remainder is [finished clone of] input value */
-                return clone(lhs).finish(set, false);
-            }
-
-        /* We need slow division */
-        res = new com.ibm.icu.math.BigDecimal(); // where we'll build result
-        res.ind = (byte) (lhs.ind * rhs.ind); // final sign (for D/I)
-        res.exp = newexp; // initial exponent (for D/I)
-        res.mant = new byte[reqdig + 1]; // where build the result
-
-        /* Now [virtually pad the mantissae with trailing zeros */
-        // Also copy the LHS, which will be our working array
-        newlen = (reqdig + reqdig) + 1;
-        var1 = extend(lhs.mant, newlen); // always makes longer, so new safe array
-        var1len = newlen; // [remaining digits are 0]
-
-        var2 = rhs.mant;
-        var2len = newlen;
-
-        /* Calculate first two digits of rhs (var2), +1 for later estimations */
-        b2b = (var2[0] * 10) + 1;
-        if (var2.length > 1)
-            b2b = b2b + var2[1];
-
-        /* start the long-division loops */
-        have = 0;
-        {
-            outer: for (;;) {
-                thisdigit = 0;
-                /* find the next digit */
-                {
-                    inner: for (;;) {
-                        if (var1len < var2len)
-                            break inner; // V1 too low
-                        if (var1len == var2len) { // compare needed
-                            {
-                                compare: do { // comparison
-                                    {
-                                        int $22 = var1len;
-                                        i = 0;
-                                        for (; $22 > 0; $22--, i++) {
-                                            // var1len is always <= var1.length
-                                            if (i < var2.length)
-                                                v2 = var2[i];
-                                            else
-                                                v2 = (byte) 0;
-                                            if (var1[i] < v2)
-                                                break inner; // V1 too low
-                                            if (var1[i] > v2)
-                                                break compare; // OK to subtract
-                                        }
-                                    }/* i */
-                                    /*
-                                     * reach here if lhs and rhs are identical; subtraction will increase digit by one,
-                                     * and the residue will be 0 so we are done; leave the loop with residue set to 0
-                                     * (in case code is 'R' or ROUND_UNNECESSARY or a ROUND_HALF_xxxx is being checked)
-                                     */
-                                    thisdigit++;
-                                    res.mant[have] = (byte) thisdigit;
-                                    have++;
-                                    var1[0] = (byte) 0; // residue to 0 [this is all we'll test]
-                                    // var1len=1 -- [optimized out]
-                                    break outer;
-                                } while (false);
-                            }/* compare */
-                            /* prepare for subtraction. Estimate BA (lengths the same) */
-                            ba = (int) var1[0]; // use only first digit
-                        } // lengths the same
-                        else {/* lhs longer than rhs */
-                            /* use first two digits for estimate */
-                            ba = var1[0] * 10;
-                            if (var1len > 1)
-                                ba = ba + var1[1];
-                        }
-                        /* subtraction needed; V1>=V2 */
-                        mult = (ba * 10) / b2b;
-                        if (mult == 0)
-                            mult = 1;
-                        thisdigit = thisdigit + mult;
-                        // subtract; var1 reusable
-                        var1 = byteaddsub(var1, var1len, var2, var2len, -mult, true);
-                        if (var1[0] != 0)
-                            continue inner; // maybe another subtract needed
-                        /*
-                         * V1 now probably has leading zeros, remove leading 0's and try again. (It could be longer than
-                         * V2)
-                         */
-                        {
-                            int $23 = var1len - 2;
-                            start = 0;
-                            start: for (; start <= $23; start++) {
-                                if (var1[start] != 0)
-                                    break start;
-                                var1len--;
-                            }
-                        }/* start */
-                        if (start == 0)
-                            continue inner;
-                        // shift left
-                        java.lang.System.arraycopy((java.lang.Object) var1, start, (java.lang.Object) var1, 0, var1len);
-                    }
-                }/* inner */
-
-                /* We have the next digit */
-                if ((have != 0) | (thisdigit != 0)) { // put the digit we got
-                    res.mant[have] = (byte) thisdigit;
-                    have++;
-                    if (have == (reqdig + 1))
-                        break outer; // we have all we need
-                    if (var1[0] == 0)
-                        break outer; // residue now 0
-                }
-                /* can leave now if a scaled divide and exponent is small enough */
-                if (scale >= 0)
-                    if (-res.exp > scale)
-                        break outer;
-                /* can leave now if not Divide and no integer part left */
-                if (code != 'D')
-                    if (res.exp <= 0)
-                        break outer;
-                res.exp = res.exp - 1; // reduce the exponent
-                /*
-                 * to get here, V1 is less than V2, so divide V2 by 10 and go for the next digit
-                 */
-                var2len--;
-            }
-        }/* outer */
-
-        /* here when we have finished dividing, for some reason */
-        // have is the number of digits we collected in res.mant
-        if (have == 0)
-            have = 1; // res.mant[0] is 0; we always want a digit
-
-        if ((code == 'I') | (code == 'R')) {/* check for integer overflow needed */
-            if ((have + res.exp) > reqdig)
-                throw new java.lang.ArithmeticException("Integer overflow");
-
-            if (code == 'R') {
-                do {
-                    /* We were doing Remainder -- return the residue */
-                    if (res.mant[0] == 0) // no integer part was found
-                        return clone(lhs).finish(set, false); // .. so return lhs, canonical
-                    if (var1[0] == 0)
-                        return ZERO; // simple 0 residue
-                    res.ind = lhs.ind; // sign is always as LHS
-                    /*
-                     * Calculate the exponent by subtracting the number of padding zeros we added and adding the
-                     * original exponent
-                     */
-                    padding = ((reqdig + reqdig) + 1) - lhs.mant.length;
-                    res.exp = (res.exp - padding) + lhs.exp;
-
-                    /*
-                     * strip insignificant padding zeros from residue, and create/copy the resulting mantissa if need be
-                     */
-                    d = var1len;
-                    {
-                        i = d - 1;
-                        i: for (; i >= 1; i--) {
-                            if (!((res.exp < lhs.exp) & (res.exp < rhs.exp)))
-                                break;
-                            if (var1[i] != 0)
-                                break i;
-                            d--;
-                            res.exp = res.exp + 1;
-                        }
-                    }/* i */
-                    if (d < var1.length) {/* need to reduce */
-                        newvar1 = new byte[d];
-                        java.lang.System.arraycopy((java.lang.Object) var1, 0, (java.lang.Object) newvar1, 0, d); // shorten
-                        var1 = newvar1;
-                    }
-                    res.mant = var1;
-                    return res.finish(set, false);
-                } while (false);
-            }/* remainder */
-        }
-
-        else {/* 'D' -- no overflow check needed */
-            // If there was a residue then bump the final digit (iff 0 or 5)
-            // so that the residue is visible for ROUND_UP, ROUND_HALF_xxx and
-            // ROUND_UNNECESSARY checks (etc.) later.
-            // [if we finished early, the residue will be 0]
-            if (var1[0] != 0) { // residue not 0
-                lasthave = res.mant[have - 1];
-                if (((lasthave % 5)) == 0)
-                    res.mant[have - 1] = (byte) (lasthave + 1);
-            }
-        }
-
-        /* Here for Divide or Integer Divide */
-        // handle scaled results first ['I' always scale 0, optional for 'D']
-        if (scale >= 0) {
-            do {
-                // say 'scale have res.exp len' scale have res.exp res.mant.length
-                if (have != res.mant.length)
-                    // already padded with 0's, so just adjust exponent
-                    res.exp = res.exp - ((res.mant.length - have));
-                // calculate number of digits we really want [may be 0]
-                actdig = res.mant.length - (-res.exp - scale);
-                res.round(actdig, set.roundingMode); // round to desired length
-                // This could have shifted left if round (say) 0.9->1[.0]
-                // Repair if so by adding a zero and reducing exponent
-                if (res.exp != -scale) {
-                    res.mant = extend(res.mant, res.mant.length + 1);
-                    res.exp = res.exp - 1;
-                }
-                return res.finish(set, true); // [strip if not PLAIN]
-            } while (false);
-        }/* scaled */
-
-        // reach here only if a non-scaled
-        if (have == res.mant.length) { // got digits+1 digits
-            res.round(set);
-            have = reqdig;
-        } else {/* have<=reqdig */
-            if (res.mant[0] == 0)
-                return ZERO; // fastpath
-            // make the mantissa truly just 'have' long
-            // [we could let finish do this, during strip, if we adjusted
-            // the exponent; however, truncation avoids the strip loop]
-            newmant = new byte[have]; // shorten
-            java.lang.System.arraycopy((java.lang.Object) res.mant, 0, (java.lang.Object) newmant, 0, have);
-            res.mant = newmant;
-        }
-        return res.finish(set, true);
-    }
-
-    /* <sgml> Report a conversion exception. </sgml> */
-
-    private void bad(char s[]) {
-        throw new java.lang.NumberFormatException("Not a number:" + " " + java.lang.String.valueOf(s));
-    }
-
-    /*
-     * <sgml> Report a bad argument to a method. </sgml> Arg1 is method name Arg2 is argument position Arg3 is what was
-     * found
-     */
-
-    private void badarg(java.lang.String name, int pos, java.lang.String value) {
-        throw new java.lang.IllegalArgumentException("Bad argument" + " " + pos + " " + "to" + " " + name + ":" + " "
-                + value);
-    }
-
-    /*
-     * <sgml> Extend byte array to given length, padding with 0s. If no extension is required then return the same
-     * array. </sgml>
-     * 
-     * Arg1 is the source byte array Arg2 is the new length (longer)
-     */
-
-    private static final byte[] extend(byte inarr[], int newlen) {
-        byte newarr[];
-        if (inarr.length == newlen)
-            return inarr;
-        newarr = new byte[newlen];
-        java.lang.System.arraycopy((java.lang.Object) inarr, 0, (java.lang.Object) newarr, 0, inarr.length);
-        // 0 padding is carried out by the JVM on allocation initialization
-        return newarr;
-    }
-
-    /*
-     * <sgml> Add or subtract two >=0 integers in byte arrays <p>This routine performs the calculation: <pre> C=A+(BM)
-     * </pre> Where M is in the range -9 through +9 <p> If M<0 then A>=B must be true, so the result is always
-     * non-negative.
-     * 
-     * Leading zeros are not removed after a subtraction. The result is either the same length as the longer of A and B,
-     * or 1 longer than that (if a carry occurred).
-     * 
-     * A is not altered unless Arg6 is 1. B is never altered.
-     * 
-     * Arg1 is A Arg2 is A length to use (if longer than A, pad with 0's) Arg3 is B Arg4 is B length to use (if longer
-     * than B, pad with 0's) Arg5 is M, the multiplier Arg6 is 1 if A can be used to build the result (if it fits)
-     * 
-     * This routine is severely performance-critical;any change here must be measured (timed) to assure no performance
-     * degradation.
-     */
-    // 1996.02.20 -- enhanced version of DMSRCN algorithm (1981)
-    // 1997.10.05 -- changed to byte arrays (from char arrays)
-    // 1998.07.01 -- changed to allow destructive reuse of LHS
-    // 1998.07.01 -- changed to allow virtual lengths for the arrays
-    // 1998.12.29 -- use lookaside for digit/carry calculation
-    // 1999.08.07 -- avoid multiply when mult=1, and make db an int
-    // 1999.12.22 -- special case m=-1, also drop 0 special case
-    private static final byte[] byteaddsub(byte a[], int avlen, byte b[], int bvlen, int m, boolean reuse) {
-        int alength;
-        int blength;
-        int ap;
-        int bp;
-        int maxarr;
-        byte reb[];
-        boolean quickm;
-        int digit;
-        int op = 0;
-        int dp90 = 0;
-        byte newarr[];
-        int i = 0;
-
-        // We'll usually be right if we assume no carry
-        alength = a.length; // physical lengths
-        blength = b.length; // ..
-        ap = avlen - 1; // -> final (rightmost) digit
-        bp = bvlen - 1; // ..
-        maxarr = bp;
-        if (maxarr < ap)
-            maxarr = ap;
-        reb = (byte[]) null; // result byte array
-        if (reuse)
-            if ((maxarr + 1) == alength)
-                reb = a; // OK to reuse A
-        if (reb == null)
-            reb = new byte[maxarr + 1]; // need new array
-
-        quickm = false; // 1 if no multiply needed
-        if (m == 1)
-            quickm = true; // most common
-        else if (m == (-1))
-            quickm = true; // also common
-
-        digit = 0; // digit, with carry or borrow
-        {
-            op = maxarr;
-            op: for (; op >= 0; op--) {
-                if (ap >= 0) {
-                    if (ap < alength)
-                        digit = digit + a[ap]; // within A
-                    ap--;
-                }
-                if (bp >= 0) {
-                    if (bp < blength) { // within B
-                        if (quickm) {
-                            if (m > 0)
-                                digit = digit + b[bp]; // most common
-                            else
-                                digit = digit - b[bp]; // also common
-                        } else
-                            digit = digit + (b[bp] * m);
-                    }
-                    bp--;
-                }
-                /* result so far (digit) could be -90 through 99 */
-                if (digit < 10)
-                    if (digit >= 0) {
-                        do { // 0-9
-                            reb[op] = (byte) digit;
-                            digit = 0; // no carry
-                            continue op;
-                        } while (false);
-                    }/* quick */
-                dp90 = digit + 90;
-                reb[op] = bytedig[dp90]; // this digit
-                digit = bytecar[dp90]; // carry or borrow
-            }
-        }/* op */
-
-        if (digit == 0)
-            return reb; // no carry
-        // following line will become an Assert, later
-        // if digit<0 then signal ArithmeticException("internal.error ["digit"]")
-
-        /* We have carry -- need to make space for the extra digit */
-        newarr = (byte[]) null;
-        if (reuse)
-            if ((maxarr + 2) == a.length)
-                newarr = a; // OK to reuse A
-        if (newarr == null)
-            newarr = new byte[maxarr + 2];
-        newarr[0] = (byte) digit; // the carried digit ..
-        // .. and all the rest [use local loop for short numbers]
-        if (maxarr < 10) {
-            int $24 = maxarr + 1;
-            i = 0;
-            for (; $24 > 0; $24--, i++) {
-                newarr[i + 1] = reb[i];
-            }
-        }/* i */
-        else
-            java.lang.System.arraycopy((java.lang.Object) reb, 0, (java.lang.Object) newarr, 1, maxarr + 1);
-        return newarr;
-    }
-
-    /*
-     * <sgml> Initializer for digit array properties (lookaside). </sgml> Returns the digit array, and initializes the
-     * carry array.
-     */
-
-    private static final byte[] diginit() {
-        byte work[];
-        int op = 0;
-        int digit = 0;
-        work = new byte[(90 + 99) + 1];
-        {
-            op = 0;
-            op: for (; op <= (90 + 99); op++) {
-                digit = op - 90;
-                if (digit >= 0) {
-                    work[op] = (byte) (digit % 10);
-                    bytecar[op] = (byte) (digit / 10); // calculate carry
-                    continue op;
-                }
-                // borrowing...
-                digit = digit + 100; // yes, this is right [consider -50]
-                work[op] = (byte) (digit % 10);
-                bytecar[op] = (byte) ((digit / 10) - 10); // calculate borrow [NB: - after %]
-            }
-        }/* op */
-        return work;
-    }
-
-    /*
-     * <sgml> Create a copy of BigDecimal object for local use. <p>This does NOT make a copy of the mantissa array.
-     * </sgml> Arg1 is the BigDecimal to clone (non-null)
-     */
-
-    private static final com.ibm.icu.math.BigDecimal clone(com.ibm.icu.math.BigDecimal dec) {
-        com.ibm.icu.math.BigDecimal copy;
-        copy = new com.ibm.icu.math.BigDecimal();
-        copy.ind = dec.ind;
-        copy.exp = dec.exp;
-        copy.form = dec.form;
-        copy.mant = dec.mant;
-        return copy;
-    }
-
-    /*
-     * <sgml> Check one or two numbers for lost digits. </sgml> Arg1 is RHS (or null, if none) Arg2 is current DIGITS
-     * setting returns quietly or throws an exception
-     */
-
-    private void checkdigits(com.ibm.icu.math.BigDecimal rhs, int dig) {
-        if (dig == 0)
-            return; // don't check if digits=0
-        // first check lhs...
-        if (this.mant.length > dig)
-            if ((!(allzero(this.mant, dig))))
-                throw new java.lang.ArithmeticException("Too many digits:" + " " + this.toString());
-        if (rhs == null)
-            return; // monadic
-        if (rhs.mant.length > dig)
-            if ((!(allzero(rhs.mant, dig))))
-                throw new java.lang.ArithmeticException("Too many digits:" + " " + rhs.toString());
-    }
-
-    /*
-     * <sgml> Round to specified digits, if necessary. </sgml> Arg1 is requested MathContext [with length and rounding
-     * mode] returns this, for convenience
-     */
-
-    private com.ibm.icu.math.BigDecimal round(com.ibm.icu.math.MathContext set) {
-        return round(set.digits, set.roundingMode);
-    }
-
-    /*
-     * <sgml> Round to specified digits, if necessary. Arg1 is requested length (digits to round to) [may be <=0 when
-     * called from format, dodivide, etc.] Arg2 is rounding mode returns this, for convenience
-     * 
-     * ind and exp are adjusted, but not cleared for a mantissa of zero
-     * 
-     * The length of the mantissa returned will be Arg1, except when Arg1 is 0, in which case the returned mantissa
-     * length will be 1. </sgml>
-     */
-
-    private com.ibm.icu.math.BigDecimal round(int len, int mode) {
-        int adjust;
-        int sign;
-        byte oldmant[];
-        boolean reuse = false;
-        byte first = 0;
-        int increment;
-        byte newmant[] = null;
-        adjust = mant.length - len;
-        if (adjust <= 0)
-            return this; // nowt to do
-
-        exp = exp + adjust; // exponent of result
-        sign = (int) ind; // save [assumes -1, 0, 1]
-        oldmant = mant; // save
-        if (len > 0) {
-            // remove the unwanted digits
-            mant = new byte[len];
-            java.lang.System.arraycopy((java.lang.Object) oldmant, 0, (java.lang.Object) mant, 0, len);
-            reuse = true; // can reuse mantissa
-            first = oldmant[len]; // first of discarded digits
-        } else {/* len<=0 */
-            mant = ZERO.mant;
-            ind = iszero;
-            reuse = false; // cannot reuse mantissa
-            if (len == 0)
-                first = oldmant[0];
-            else
-                first = (byte) 0; // [virtual digit]
-        }
-
-        // decide rounding adjustment depending on mode, sign, and discarded digits
-        increment = 0; // bumper
-        {
-            do {/* select */
-                if (mode == ROUND_HALF_UP) { // default first [most common]
-                    if (first >= 5)
-                        increment = sign;
-                } else if (mode == ROUND_UNNECESSARY) { // default for setScale()
-                    // discarding any non-zero digits is an error
-                    if ((!(allzero(oldmant, len))))
-                        throw new java.lang.ArithmeticException("Rounding necessary");
-                } else if (mode == ROUND_HALF_DOWN) { // 0.5000 goes down
-                    if (first > 5)
-                        increment = sign;
-                    else if (first == 5)
-                        if ((!(allzero(oldmant, len + 1))))
-                            increment = sign;
-                } else if (mode == ROUND_HALF_EVEN) { // 0.5000 goes down if left digit even
-                    if (first > 5)
-                        increment = sign;
-                    else if (first == 5) {
-                        if ((!(allzero(oldmant, len + 1))))
-                            increment = sign;
-                        else /* 0.5000 */
-                        if ((((mant[mant.length - 1]) % 2)) == 1)
-                            increment = sign;
-                    }
-                } else if (mode == ROUND_DOWN) {
-                    // never increment
-                } else if (mode == ROUND_UP) { // increment if discarded non-zero
-                    if ((!(allzero(oldmant, len))))
-                        increment = sign;
-                } else if (mode == ROUND_CEILING) { // more positive
-                    if (sign > 0)
-                        if ((!(allzero(oldmant, len))))
-                            increment = sign;
-                } else if (mode == ROUND_FLOOR) { // more negative
-                    if (sign < 0)
-                        if ((!(allzero(oldmant, len))))
-                            increment = sign;
-                } else {
-                    throw new java.lang.IllegalArgumentException("Bad round value:" + " " + mode);
-                }
-            } while (false);
-        }/* modes */
-
-        if (increment != 0) {
-            do {
-                if (ind == iszero) {
-                    // we must not subtract from 0, but result is trivial anyway
-                    mant = ONE.mant;
-                    ind = (byte) increment;
-                } else {
-                    // mantissa is non-0; we can safely add or subtract 1
-                    if (ind == isneg)
-                        increment = -increment;
-                    newmant = byteaddsub(mant, mant.length, ONE.mant, 1, increment, reuse);
-                    if (newmant.length > mant.length) { // had a carry
-                        // drop rightmost digit and raise exponent
-                        exp++;
-                        // mant is already the correct length
-                        java.lang.System.arraycopy((java.lang.Object) newmant, 0, (java.lang.Object) mant, 0,
-                                mant.length);
-                    } else
-                        mant = newmant;
-                }
-            } while (false);
-        }/* bump */
-        // rounding can increase exponent significantly
-        if (exp > MaxExp)
-            throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + exp);
-        return this;
-    }
-
-    /*
-     * <sgml> Test if rightmost digits are all 0. Arg1 is a mantissa array to test Arg2 is the offset of first digit to
-     * check [may be negative; if so, digits to left are 0's] returns 1 if all the digits starting at Arg2 are 0
-     * 
-     * Arg2 may be beyond array bounds, in which case 1 is returned </sgml>
-     */
-
-    private static final boolean allzero(byte array[], int start) {
-        int i = 0;
-        if (start < 0)
-            start = 0;
-        {
-            int $25 = array.length - 1;
-            i = start;
-            for (; i <= $25; i++) {
-                if (array[i] != 0)
-                    return false;
-            }
-        }/* i */
-        return true;
-    }
-
-    /*
-     * <sgml> Carry out final checks and canonicalization <p> This finishes off the current number by: 1. Rounding if
-     * necessary (NB: length includes leading zeros) 2. Stripping trailing zeros (if requested and \PLAIN) 3. Stripping
-     * leading zeros (always) 4. Selecting exponential notation (if required) 5. Converting a zero result to just '0'
-     * (if \PLAIN) In practice, these operations overlap and share code. It always sets form. </sgml> Arg1 is requested
-     * MathContext (length to round to, trigger, and FORM) Arg2 is 1 if trailing insignificant zeros should be removed
-     * after round (for division, etc.), provided that set.form isn't PLAIN. returns this, for convenience
-     */
-
-    private com.ibm.icu.math.BigDecimal finish(com.ibm.icu.math.MathContext set, boolean strip) {
-        int d = 0;
-        int i = 0;
-        byte newmant[] = null;
-        int mag = 0;
-        int sig = 0;
-        /* Round if mantissa too long and digits requested */
-        if (set.digits != 0)
-            if (this.mant.length > set.digits)
-                this.round(set);
-
-        /*
-         * If strip requested (and standard formatting), remove insignificant trailing zeros.
-         */
-        if (strip)
-            if (set.form != com.ibm.icu.math.MathContext.PLAIN) {
-                d = this.mant.length;
-                /* see if we need to drop any trailing zeros */
-                {
-                    i = d - 1;
-                    i: for (; i >= 1; i--) {
-                        if (this.mant[i] != 0)
-                            break i;
-                        d--;
-                        exp++;
-                    }
-                }/* i */
-                if (d < this.mant.length) {/* need to reduce */
-                    newmant = new byte[d];
-                    java.lang.System.arraycopy((java.lang.Object) this.mant, 0, (java.lang.Object) newmant, 0, d);
-                    this.mant = newmant;
-                }
-            }
-
-        form = (byte) com.ibm.icu.math.MathContext.PLAIN; // preset
-
-        /* Now check for leading- and all- zeros in mantissa */
-        {
-            int $26 = this.mant.length;
-            i = 0;
-            for (; $26 > 0; $26--, i++) {
-                if (this.mant[i] != 0) {
-                    // non-0 result; ind will be correct
-                    // remove leading zeros [e.g., after subtract]
-                    if (i > 0) {
-                        do {
-                            newmant = new byte[this.mant.length - i];
-                            java.lang.System.arraycopy((java.lang.Object) this.mant, i, (java.lang.Object) newmant, 0,
-                                    this.mant.length - i);
-                            this.mant = newmant;
-                        } while (false);
-                    }/* delead */
-                    // now determine form if not PLAIN
-                    mag = exp + mant.length;
-                    if (mag > 0) { // most common path
-                        if (mag > set.digits)
-                            if (set.digits != 0)
-                                form = (byte) set.form;
-                        if ((mag - 1) <= MaxExp)
-                            return this; // no overflow; quick return
-                    } else if (mag < (-5))
-                        form = (byte) set.form;
-                    /* check for overflow */
-                    mag--;
-                    if ((mag < MinExp) | (mag > MaxExp)) {
-                        overflow: do {
-                            // possible reprieve if form is engineering
-                            if (form == com.ibm.icu.math.MathContext.ENGINEERING) {
-                                sig = mag % 3; // leftover
-                                if (sig < 0)
-                                    sig = 3 + sig; // negative exponent
-                                mag = mag - sig; // exponent to use
-                                // 1999.06.29: second test here must be MaxExp
-                                if (mag >= MinExp)
-                                    if (mag <= MaxExp)
-                                        break overflow;
-                            }
-                            throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + mag);
-                        } while (false);
-                    }/* overflow */
-                    return this;
-                }
-            }
-        }/* i */
-
-        // Drop through to here only if mantissa is all zeros
-        ind = iszero;
-        {/* select */
-            if (set.form != com.ibm.icu.math.MathContext.PLAIN)
-                exp = 0; // standard result; go to '0'
-            else if (exp > 0)
-                exp = 0; // +ve exponent also goes to '0'
-            else {
-                // a plain number with -ve exponent; preserve and check exponent
-                if (exp < MinExp)
-                    throw new java.lang.ArithmeticException("Exponent Overflow:" + " " + exp);
-            }
-        }
-        mant = ZERO.mant; // canonical mantissa
-        return this;
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/MathContext.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/MathContext.java
deleted file mode 100644
index bf0c93f..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/math/MathContext.java
+++ /dev/null
@@ -1,603 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/* Generated from 'MathContext.nrx' 8 Sep 2000 11:07:48 [v2.00] */
-/* Options: Binary Comments Crossref Format Java Logo Strictargs Strictcase Trace2 Verbose3 */
-package com.ibm.icu.math;
-
-/* ------------------------------------------------------------------ */
-/* MathContext -- Math context settings                               */
-/* ------------------------------------------------------------------ */
-/* Copyright IBM Corporation, 1997-2011.  All Rights Reserved.        */
-/*                                                                    */
-/*   The MathContext object encapsulates the settings used by the     */
-/*   BigDecimal class; it could also be used by other arithmetics.    */
-/* ------------------------------------------------------------------ */
-/* Notes:                                                             */
-/*                                                                    */
-/* 1. The properties are checked for validity on construction, so     */
-/*    the BigDecimal class may assume that they are correct.          */
-/* ------------------------------------------------------------------ */
-/* Author:    Mike Cowlishaw                                          */
-/* 1997.09.03 Initial version (edited from netrexx.lang.RexxSet)      */
-/* 1997.09.12 Add lostDigits property                                 */
-/* 1998.05.02 Make the class immutable and final; drop set methods    */
-/* 1998.06.05 Add Round (rounding modes) property                     */
-/* 1998.06.25 Rename from DecimalContext; allow digits=0              */
-/* 1998.10.12 change to com.ibm.icu.math package                          */
-/* 1999.02.06 add javadoc comments                                    */
-/* 1999.03.05 simplify; changes from discussion with J. Bloch         */
-/* 1999.03.13 1.00 release to IBM Centre for Java Technology          */
-/* 1999.07.10 1.04 flag serialization unused                          */
-/* 2000.01.01 1.06 copyright update                                   */
-/* ------------------------------------------------------------------ */
-
-
-
-
-/**
- * The <code>MathContext</code> immutable class encapsulates the
- * settings understood by the operator methods of the {@link BigDecimal}
- * class (and potentially other classes).  Operator methods are those
- * that effect an operation on a number or a pair of numbers.
- * <p>
- * The settings, which are not base-dependent, comprise:
- * <ol>
- * <li><code>digits</code>:
- * the number of digits (precision) to be used for an operation
- * <li><code>form</code>:
- * the form of any exponent that results from the operation
- * <li><code>lostDigits</code>:
- * whether checking for lost digits is enabled
- * <li><code>roundingMode</code>:
- * the algorithm to be used for rounding.
- * </ol>
- * <p>
- * When provided, a <code>MathContext</code> object supplies the
- * settings for an operation directly.
- * <p>
- * When <code>MathContext.DEFAULT</code> is provided for a
- * <code>MathContext</code> parameter then the default settings are used
- * (<code>9, SCIENTIFIC, false, ROUND_HALF_UP</code>).
- * <p>
- * In the <code>BigDecimal</code> class, all methods which accept a
- * <code>MathContext</code> object defaults) also have a version of the
- * method which does not accept a MathContext parameter.  These versions
- * carry out unlimited precision fixed point arithmetic (as though the
- * settings were (<code>0, PLAIN, false, ROUND_HALF_UP</code>).
- * <p>
- * The instance variables are shared with default access (so they are
- * directly accessible to the <code>BigDecimal</code> class), but must
- * never be changed.
- * <p>
- * The rounding mode constants have the same names and values as the
- * constants of the same name in <code>java.math.BigDecimal</code>, to
- * maintain compatibility with earlier versions of
- * <code>BigDecimal</code>.
- *
- * @see     BigDecimal
- * @author  Mike Cowlishaw
- * @stable ICU 2.0
- */
-
-public final class MathContext implements java.io.Serializable{
- //private static final java.lang.String $0="MathContext.nrx";
- 
- /* ----- Properties ----- */
- /* properties public constant */
- /**
-  * Plain (fixed point) notation, without any exponent.
-  * Used as a setting to control the form of the result of a
-  * <code>BigDecimal</code> operation.
-  * A zero result in plain form may have a decimal part of one or
-  * more zeros.
-  *
-  * @see #ENGINEERING
-  * @see #SCIENTIFIC
-  * @stable ICU 2.0
-  */
- public static final int PLAIN=0; // [no exponent]
- 
- /**
-  * Standard floating point notation (with scientific exponential
-  * format, where there is one digit before any decimal point).
-  * Used as a setting to control the form of the result of a
-  * <code>BigDecimal</code> operation.
-  * A zero result in plain form may have a decimal part of one or
-  * more zeros.
-  *
-  * @see #ENGINEERING
-  * @see #PLAIN
-  * @stable ICU 2.0
-  */
- public static final int SCIENTIFIC=1; // 1 digit before .
- 
- /**
-  * Standard floating point notation (with engineering exponential
-  * format, where the power of ten is a multiple of 3).
-  * Used as a setting to control the form of the result of a
-  * <code>BigDecimal</code> operation.
-  * A zero result in plain form may have a decimal part of one or
-  * more zeros.
-  *
-  * @see #PLAIN
-  * @see #SCIENTIFIC
-  * @stable ICU 2.0
-  */
- public static final int ENGINEERING=2; // 1-3 digits before .
- 
- // The rounding modes match the original BigDecimal class values
- /**
-  * Rounding mode to round to a more positive number.
-  * Used as a setting to control the rounding mode used during a
-  * <code>BigDecimal</code> operation.
-  * <p>
-  * If any of the discarded digits are non-zero then the result
-  * should be rounded towards the next more positive digit.
-  * @stable ICU 2.0
-  */
- public static final int ROUND_CEILING=2;
- 
- /**
-  * Rounding mode to round towards zero.
-  * Used as a setting to control the rounding mode used during a
-  * <code>BigDecimal</code> operation.
-  * <p>
-  * All discarded digits are ignored (truncated).  The result is
-  * neither incremented nor decremented.
-  * @stable ICU 2.0
-  */
- public static final int ROUND_DOWN=1;
- 
- /**
-  * Rounding mode to round to a more negative number.
-  * Used as a setting to control the rounding mode used during a
-  * <code>BigDecimal</code> operation.
-  * <p>
-  * If any of the discarded digits are non-zero then the result
-  * should be rounded towards the next more negative digit.
-  * @stable ICU 2.0
-  */
- public static final int ROUND_FLOOR=3;
- 
- /**
-  * Rounding mode to round to nearest neighbor, where an equidistant
-  * value is rounded down.
-  * Used as a setting to control the rounding mode used during a
-  * <code>BigDecimal</code> operation.
-  * <p>
-  * If the discarded digits represent greater than half (0.5 times)
-  * the value of a one in the next position then the result should be
-  * rounded up (away from zero).  Otherwise the discarded digits are
-  * ignored.
-  * @stable ICU 2.0
-  */
- public static final int ROUND_HALF_DOWN=5;
- 
- /**
-  * Rounding mode to round to nearest neighbor, where an equidistant
-  * value is rounded to the nearest even neighbor.
-  * Used as a setting to control the rounding mode used during a
-  * <code>BigDecimal</code> operation.
-  * <p>
-  * If the discarded digits represent greater than half (0.5 times)
-  * the value of a one in the next position then the result should be
-  * rounded up (away from zero).  If they represent less than half,
-  * then the result should be rounded down.
-  * <p>
-  * Otherwise (they represent exactly half) the result is rounded
-  * down if its rightmost digit is even, or rounded up if its
-  * rightmost digit is odd (to make an even digit).
-  * @stable ICU 2.0
-  */
- public static final int ROUND_HALF_EVEN=6;
- 
- /**
-  * Rounding mode to round to nearest neighbor, where an equidistant
-  * value is rounded up.
-  * Used as a setting to control the rounding mode used during a
-  * <code>BigDecimal</code> operation.
-  * <p>
-  * If the discarded digits represent greater than or equal to half
-  * (0.5 times) the value of a one in the next position then the result
-  * should be rounded up (away from zero).  Otherwise the discarded
-  * digits are ignored.
-  * @stable ICU 2.0
-  */
- public static final int ROUND_HALF_UP=4;
- 
- /**
-  * Rounding mode to assert that no rounding is necessary.
-  * Used as a setting to control the rounding mode used during a
-  * <code>BigDecimal</code> operation.
-  * <p>
-  * Rounding (potential loss of information) is not permitted.
-  * If any of the discarded digits are non-zero then an
-  * <code>ArithmeticException</code> should be thrown.
-  * @stable ICU 2.0
-  */
- public static final int ROUND_UNNECESSARY=7;
- 
- /**
-  * Rounding mode to round away from zero.
-  * Used as a setting to control the rounding mode used during a
-  * <code>BigDecimal</code> operation.
-  * <p>
-  * If any of the discarded digits are non-zero then the result will
-  * be rounded up (away from zero).
-  * @stable ICU 2.0
-  */
- public static final int ROUND_UP=0;
- 
- 
- /* properties shared */
- /**
-  * The number of digits (precision) to be used for an operation.
-  * A value of 0 indicates that unlimited precision (as many digits
-  * as are required) will be used.
-  * <p>
-  * The {@link BigDecimal} operator methods use this value to
-  * determine the precision of results.
-  * Note that leading zeros (in the integer part of a number) are
-  * never significant.
-  * <p>
-  * <code>digits</code> will always be non-negative.
-  *
-  * @serial
-  */
- int digits;
- 
- /**
-  * The form of results from an operation.
-  * <p>
-  * The {@link BigDecimal} operator methods use this value to
-  * determine the form of results, in particular whether and how
-  * exponential notation should be used.
-  *
-  * @see #ENGINEERING
-  * @see #PLAIN
-  * @see #SCIENTIFIC
-  * @serial
-  */
- int form; // values for this must fit in a byte
- 
- /**
-  * Controls whether lost digits checking is enabled for an
-  * operation.
-  * Set to <code>true</code> to enable checking, or
-  * to <code>false</code> to disable checking.
-  * <p>
-  * When enabled, the {@link BigDecimal} operator methods check
-  * the precision of their operand or operands, and throw an
-  * <code>ArithmeticException</code> if an operand is more precise
-  * than the digits setting (that is, digits would be lost).
-  * When disabled, operands are rounded to the specified digits.
-  *
-  * @serial
-  */
- boolean lostDigits;
- 
- /**
-  * The rounding algorithm to be used for an operation.
-  * <p>
-  * The {@link BigDecimal} operator methods use this value to
-  * determine the algorithm to be used when non-zero digits have to
-  * be discarded in order to reduce the precision of a result.
-  * The value must be one of the public constants whose name starts
-  * with <code>ROUND_</code>.
-  *
-  * @see #ROUND_CEILING
-  * @see #ROUND_DOWN
-  * @see #ROUND_FLOOR
-  * @see #ROUND_HALF_DOWN
-  * @see #ROUND_HALF_EVEN
-  * @see #ROUND_HALF_UP
-  * @see #ROUND_UNNECESSARY
-  * @see #ROUND_UP
-  * @serial
-  */
- int roundingMode;
- 
- /* properties private constant */
- // default settings
- private static final int DEFAULT_FORM=SCIENTIFIC;
- private static final int DEFAULT_DIGITS=9;
- private static final boolean DEFAULT_LOSTDIGITS=false;
- private static final int DEFAULT_ROUNDINGMODE=ROUND_HALF_UP;
- 
- /* properties private constant */
- 
- private static final int MIN_DIGITS=0; // smallest value for DIGITS.
- private static final int MAX_DIGITS=999999999; // largest value for DIGITS.  If increased,
- // the BigDecimal class may need update.
- // list of valid rounding mode values, most common two first
- private static final int ROUNDS[]=new int[]{ROUND_HALF_UP,ROUND_UNNECESSARY,ROUND_CEILING,ROUND_DOWN,ROUND_FLOOR,ROUND_HALF_DOWN,ROUND_HALF_EVEN,ROUND_UP};
- 
- 
- private static final java.lang.String ROUNDWORDS[]=new java.lang.String[]{"ROUND_HALF_UP","ROUND_UNNECESSARY","ROUND_CEILING","ROUND_DOWN","ROUND_FLOOR","ROUND_HALF_DOWN","ROUND_HALF_EVEN","ROUND_UP"}; // matching names of the ROUNDS values
- 
- 
- 
- 
- /* properties private constant unused */
- 
- // Serialization version
- private static final long serialVersionUID=7163376998892515376L;
- 
- /* properties public constant */
- /**
-  * A <code>MathContext</code> object initialized to the default
-  * settings for general-purpose arithmetic.  That is,
-  * <code>digits=9 form=SCIENTIFIC lostDigits=false
-  * roundingMode=ROUND_HALF_UP</code>.
-  *
-  * @see #SCIENTIFIC
-  * @see #ROUND_HALF_UP
-  * @stable ICU 2.0
-  */
- public static final com.ibm.icu.math.MathContext DEFAULT=new com.ibm.icu.math.MathContext(DEFAULT_DIGITS,DEFAULT_FORM,DEFAULT_LOSTDIGITS,DEFAULT_ROUNDINGMODE);
-
- 
- 
- 
- /* ----- Constructors ----- */
- 
- /**
-  * Constructs a new <code>MathContext</code> with a specified
-  * precision.
-  * The other settings are set to the default values
-  * (see {@link #DEFAULT}).
-  *
-  * An <code>IllegalArgumentException</code> is thrown if the
-  * <code>setdigits</code> parameter is out of range
-  * (&lt;0 or &gt;999999999).
-  *
-  * @param setdigits     The <code>int</code> digits setting
-  *                      for this <code>MathContext</code>.
-  * @throws IllegalArgumentException parameter out of range.
-  * @stable ICU 2.0
-  */
- 
- public MathContext(int setdigits){
-  this(setdigits,DEFAULT_FORM,DEFAULT_LOSTDIGITS,DEFAULT_ROUNDINGMODE);
-  return;}
-
- 
- /**
-  * Constructs a new <code>MathContext</code> with a specified
-  * precision and form.
-  * The other settings are set to the default values
-  * (see {@link #DEFAULT}).
-  *
-  * An <code>IllegalArgumentException</code> is thrown if the
-  * <code>setdigits</code> parameter is out of range
-  * (&lt;0 or &gt;999999999), or if the value given for the
-  * <code>setform</code> parameter is not one of the appropriate
-  * constants.
-  *
-  * @param setdigits     The <code>int</code> digits setting
-  *                      for this <code>MathContext</code>.
-  * @param setform       The <code>int</code> form setting
-  *                      for this <code>MathContext</code>.
-  * @throws IllegalArgumentException parameter out of range.
-  * @stable ICU 2.0
-  */
- 
- public MathContext(int setdigits,int setform){
-  this(setdigits,setform,DEFAULT_LOSTDIGITS,DEFAULT_ROUNDINGMODE);
-  return;}
-
- /**
-  * Constructs a new <code>MathContext</code> with a specified
-  * precision, form, and lostDigits setting.
-  * The roundingMode setting is set to its default value
-  * (see {@link #DEFAULT}).
-  *
-  * An <code>IllegalArgumentException</code> is thrown if the
-  * <code>setdigits</code> parameter is out of range
-  * (&lt;0 or &gt;999999999), or if the value given for the
-  * <code>setform</code> parameter is not one of the appropriate
-  * constants.
-  *
-  * @param setdigits     The <code>int</code> digits setting
-  *                      for this <code>MathContext</code>.
-  * @param setform       The <code>int</code> form setting
-  *                      for this <code>MathContext</code>.
-  * @param setlostdigits The <code>boolean</code> lostDigits
-  *                      setting for this <code>MathContext</code>.
-  * @throws IllegalArgumentException parameter out of range.
-  * @stable ICU 2.0
-  */
- 
- public MathContext(int setdigits,int setform,boolean setlostdigits){
-  this(setdigits,setform,setlostdigits,DEFAULT_ROUNDINGMODE);
-  return;}
-
- /**
-  * Constructs a new <code>MathContext</code> with a specified
-  * precision, form, lostDigits, and roundingMode setting.
-  *
-  * An <code>IllegalArgumentException</code> is thrown if the
-  * <code>setdigits</code> parameter is out of range
-  * (&lt;0 or &gt;999999999), or if the value given for the
-  * <code>setform</code> or <code>setroundingmode</code> parameters is
-  * not one of the appropriate constants.
-  *
-  * @param setdigits       The <code>int</code> digits setting
-  *                        for this <code>MathContext</code>.
-  * @param setform         The <code>int</code> form setting
-  *                        for this <code>MathContext</code>.
-  * @param setlostdigits   The <code>boolean</code> lostDigits
-  *                        setting for this <code>MathContext</code>.
-  * @param setroundingmode The <code>int</code> roundingMode setting
-  *                        for this <code>MathContext</code>.
-  * @throws IllegalArgumentException parameter out of range.
-  * @stable ICU 2.0
-  */
- 
- public MathContext(int setdigits,int setform,boolean setlostdigits,int setroundingmode){super();
-  
-  
-  // set values, after checking
-  if (setdigits!=DEFAULT_DIGITS) 
-   {
-    if (setdigits<MIN_DIGITS) 
-     throw new java.lang.IllegalArgumentException("Digits too small:"+" "+setdigits);
-    if (setdigits>MAX_DIGITS) 
-     throw new java.lang.IllegalArgumentException("Digits too large:"+" "+setdigits);
-   }
-  {/*select*/
-  if (setform==SCIENTIFIC){
-   // [most common]
-  }else if (setform==ENGINEERING){
-  }else if (setform==PLAIN){
-  }else{
-   throw new java.lang.IllegalArgumentException("Bad form value:"+" "+setform);
-  }
-  }
-  if ((!(isValidRound(setroundingmode)))) 
-   throw new java.lang.IllegalArgumentException("Bad roundingMode value:"+" "+setroundingmode);
-  digits=setdigits;
-  form=setform;
-  lostDigits=setlostdigits; // [no bad value possible]
-  roundingMode=setroundingmode;
-  return;}
-
- /**
-  * Returns the digits setting.
-  * This value is always non-negative.
-  *
-  * @return an <code>int</code> which is the value of the digits
-  *         setting
-  * @stable ICU 2.0
-  */
- 
- public int getDigits(){
-  return digits;
-  }
-
- /**
-  * Returns the form setting.
-  * This will be one of
-  * {@link #ENGINEERING},
-  * {@link #PLAIN}, or
-  * {@link #SCIENTIFIC}.
-  *
-  * @return an <code>int</code> which is the value of the form setting
-  * @stable ICU 2.0
-  */
- 
- public int getForm(){
-  return form;
-  }
-
- /**
-  * Returns the lostDigits setting.
-  * This will be either <code>true</code> (enabled) or
-  * <code>false</code> (disabled).
-  *
-  * @return a <code>boolean</code> which is the value of the lostDigits
-  *           setting
-  * @stable ICU 2.0
-  */
- 
- public boolean getLostDigits(){
-  return lostDigits;
-  }
-
- /**
-  * Returns the roundingMode setting.
-  * This will be one of
-  * {@link  #ROUND_CEILING},
-  * {@link  #ROUND_DOWN},
-  * {@link  #ROUND_FLOOR},
-  * {@link  #ROUND_HALF_DOWN},
-  * {@link  #ROUND_HALF_EVEN},
-  * {@link  #ROUND_HALF_UP},
-  * {@link  #ROUND_UNNECESSARY}, or
-  * {@link  #ROUND_UP}.
-  *
-  * @return an <code>int</code> which is the value of the roundingMode
-  *         setting
-  * @stable ICU 2.0
-  */
- 
- public int getRoundingMode(){
-  return roundingMode;
-  }
-
- /** Returns the <code>MathContext</code> as a readable string.
-  * The <code>String</code> returned represents the settings of the
-  * <code>MathContext</code> object as four blank-delimited words
-  * separated by a single blank and with no leading or trailing blanks,
-  * as follows:
-  * <ol>
-  * <li>
-  * <code>digits=</code>, immediately followed by
-  * the value of the digits setting as a numeric word.
-  * <li>
-  * <code>form=</code>, immediately followed by
-  * the value of the form setting as an uppercase word
-  * (one of <code>SCIENTIFIC</code>, <code>PLAIN</code>, or
-  * <code>ENGINEERING</code>).
-  * <li>
-  * <code>lostDigits=</code>, immediately followed by
-  * the value of the lostDigits setting
-  * (<code>1</code> if enabled, <code>0</code> if disabled).
-  * <li>
-  * <code>roundingMode=</code>, immediately followed by
-  * the value of the roundingMode setting as a word.
-  * This word will be the same as the name of the corresponding public
-  * constant.
-  * </ol>
-  * <p>
-  * For example:
-  * <br><code>
-  * digits=9 form=SCIENTIFIC lostDigits=0 roundingMode=ROUND_HALF_UP
-  * </code>
-  * <p>
-  * Additional words may be appended to the result of
-  * <code>toString</code> in the future if more properties are added
-  * to the class.
-  *
-  * @return a <code>String</code> representing the context settings.
-  * @stable ICU 2.0
-  */
- 
- public java.lang.String toString(){
-  java.lang.String formstr=null;
-  int r=0;
-  java.lang.String roundword=null;
-  {/*select*/
-  if (form==SCIENTIFIC)
-   formstr="SCIENTIFIC";
-  else if (form==ENGINEERING)
-   formstr="ENGINEERING";
-  else{
-   formstr="PLAIN";/* form=PLAIN */
-  }
-  }
-  {int $1=ROUNDS.length;r=0;r:for(;$1>0;$1--,r++){
-   if (roundingMode==ROUNDS[r]) 
-    {
-     roundword=ROUNDWORDS[r];
-     break r;
-    }
-   }
-  }/*r*/
-  return "digits="+digits+" "+"form="+formstr+" "+"lostDigits="+(lostDigits?"1":"0")+" "+"roundingMode="+roundword;
-  }
-
- 
- /* <sgml> Test whether round is valid. </sgml> */
- // This could be made shared for use by BigDecimal for setScale.
- 
- private static boolean isValidRound(int testround){
-  int r=0;
-  {int $2=ROUNDS.length;for(r=0;$2>0;$2--,r++){
-   if (testround==ROUNDS[r]) 
-    return true;
-   }
-  }/*r*/
-  return false;
-  }
- }
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Bidi.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Bidi.java
deleted file mode 100644
index edf69d7..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Bidi.java
+++ /dev/null
@@ -1,2683 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
-*******************************************************************************
-*   Copyright (C) 2001-2012, International Business Machines
-*   Corporation and others.  All Rights Reserved.
-*******************************************************************************
-*/
-
-/* FOOD FOR THOUGHT: currently the reordering modes are a mixture of
- * algorithm for direct BiDi, algorithm for inverse Bidi and the bizarre
- * concept of RUNS_ONLY which is a double operation.
- * It could be advantageous to divide this into 3 concepts:
- * a) Operation: direct / inverse / RUNS_ONLY
- * b) Direct algorithm: default / NUMBERS_SPECIAL / GROUP_NUMBERS_WITH_L
- * c) Inverse algorithm: default / INVERSE_LIKE_DIRECT / NUMBERS_SPECIAL
- * This would allow combinations not possible today like RUNS_ONLY with
- * NUMBERS_SPECIAL.
- * Also allow to set INSERT_MARKS for the direct step of RUNS_ONLY and
- * REMOVE_CONTROLS for the inverse step.
- * Not all combinations would be supported, and probably not all do make sense.
- * This would need to document which ones are supported and what are the
- * fallbacks for unsupported combinations.
- */
-
-//TODO: make sample program do something simple but real and complete
-
-package com.ibm.icu.text;
-
-import java.text.AttributedCharacterIterator;
-
-/**
- *
- * <h2>Bidi algorithm for ICU</h2>
- *
- * This is an implementation of the Unicode Bidirectional algorithm. The
- * algorithm is defined in the <a
- * href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Annex #9</a>,
- * version 13, also described in The Unicode Standard, Version 4.0 .
- * <p>
- *
- * Note: Libraries that perform a bidirectional algorithm and reorder strings
- * accordingly are sometimes called "Storage Layout Engines". ICU's Bidi and
- * shaping (ArabicShaping) classes can be used at the core of such "Storage
- * Layout Engines".
- *
- * <h3>General remarks about the API:</h3>
- *
- * The &quot;limit&quot; of a sequence of characters is the position just after
- * their last character, i.e., one more than that position.
- * <p>
- *
- * Some of the API methods provide access to &quot;runs&quot;. Such a
- * &quot;run&quot; is defined as a sequence of characters that are at the same
- * embedding level after performing the Bidi algorithm.
- * <p>
- *
- * <h3>Basic concept: paragraph</h3>
- * A piece of text can be divided into several paragraphs by characters
- * with the Bidi class <code>Block Separator</code>. For handling of
- * paragraphs, see:
- * <ul>
- * <li>{@link #countParagraphs}
- * <li>{@link #getParaLevel}
- * <li>{@link #getParagraph}
- * <li>{@link #getParagraphByIndex}
- * </ul>
- *
- * <h3>Basic concept: text direction</h3>
- * The direction of a piece of text may be:
- * <ul>
- * <li>{@link #LTR}
- * <li>{@link #RTL}
- * <li>{@link #MIXED}
- * </ul>
- *
- * <h3>Basic concept: levels</h3>
- *
- * Levels in this API represent embedding levels according to the Unicode
- * Bidirectional Algorithm.
- * Their low-order bit (even/odd value) indicates the visual direction.<p>
- *
- * Levels can be abstract values when used for the
- * <code>paraLevel</code> and <code>embeddingLevels</code>
- * arguments of <code>setPara()</code>; there:
- * <ul>
- * <li>the high-order bit of an <code>embeddingLevels[]</code>
- * value indicates whether the using application is
- * specifying the level of a character to <i>override</i> whatever the
- * Bidi implementation would resolve it to.</li>
- * <li><code>paraLevel</code> can be set to the
- * pseudo-level values <code>LEVEL_DEFAULT_LTR</code>
- * and <code>LEVEL_DEFAULT_RTL</code>.</li>
- * </ul>
- *
- * <p>The related constants are not real, valid level values.
- * <code>DEFAULT_XXX</code> can be used to specify
- * a default for the paragraph level for
- * when the <code>setPara()</code> method
- * shall determine it but there is no
- * strongly typed character in the input.<p>
- *
- * Note that the value for <code>LEVEL_DEFAULT_LTR</code> is even
- * and the one for <code>LEVEL_DEFAULT_RTL</code> is odd,
- * just like with normal LTR and RTL level values -
- * these special values are designed that way. Also, the implementation
- * assumes that MAX_EXPLICIT_LEVEL is odd.
- *
- * <ul><b>See Also:</b>
- * <li>{@link #LEVEL_DEFAULT_LTR}
- * <li>{@link #LEVEL_DEFAULT_RTL}
- * <li>{@link #LEVEL_OVERRIDE}
- * <li>{@link #MAX_EXPLICIT_LEVEL}
- * <li>{@link #setPara}
- * </ul>
- *
- * <h3>Basic concept: Reordering Mode</h3>
- * Reordering mode values indicate which variant of the Bidi algorithm to
- * use.
- *
- * <ul><b>See Also:</b>
- * <li>{@link #setReorderingMode}
- * <li>{@link #REORDER_DEFAULT}
- * <li>{@link #REORDER_NUMBERS_SPECIAL}
- * <li>{@link #REORDER_GROUP_NUMBERS_WITH_R}
- * <li>{@link #REORDER_RUNS_ONLY}
- * <li>{@link #REORDER_INVERSE_NUMBERS_AS_L}
- * <li>{@link #REORDER_INVERSE_LIKE_DIRECT}
- * <li>{@link #REORDER_INVERSE_FOR_NUMBERS_SPECIAL}
- * </ul>
- *
- * <h3>Basic concept: Reordering Options</h3>
- * Reordering options can be applied during Bidi text transformations.
- * <ul><b>See Also:</b>
- * <li>{@link #setReorderingOptions}
- * <li>{@link #OPTION_DEFAULT}
- * <li>{@link #OPTION_INSERT_MARKS}
- * <li>{@link #OPTION_REMOVE_CONTROLS}
- * <li>{@link #OPTION_STREAMING}
- * </ul>
- *
- *
- * @author Simon Montagu, Matitiahu Allouche (ported from C code written by Markus W. Scherer)
- * @stable ICU 3.8
- *
- *
- * <h4> Sample code for the ICU Bidi API </h4>
- *
- * <h5>Rendering a paragraph with the ICU Bidi API</h5>
- *
- * This is (hypothetical) sample code that illustrates how the ICU Bidi API
- * could be used to render a paragraph of text. Rendering code depends highly on
- * the graphics system, therefore this sample code must make a lot of
- * assumptions, which may or may not match any existing graphics system's
- * properties.
- *
- * <p>
- * The basic assumptions are:
- * </p>
- * <ul>
- * <li>Rendering is done from left to right on a horizontal line.</li>
- * <li>A run of single-style, unidirectional text can be rendered at once.
- * </li>
- * <li>Such a run of text is passed to the graphics system with characters
- * (code units) in logical order.</li>
- * <li>The line-breaking algorithm is very complicated and Locale-dependent -
- * and therefore its implementation omitted from this sample code.</li>
- * </ul>
- *
- * <pre>
- *
- *  package com.ibm.icu.dev.test.bidi;
- *
- *  import com.ibm.icu.text.Bidi;
- *  import com.ibm.icu.text.BidiRun;
- *
- *  public class Sample {
- *
- *      static final int styleNormal = 0;
- *      static final int styleSelected = 1;
- *      static final int styleBold = 2;
- *      static final int styleItalics = 4;
- *      static final int styleSuper=8;
- *      static final int styleSub = 16;
- *
- *      static class StyleRun {
- *          int limit;
- *          int style;
- *
- *          public StyleRun(int limit, int style) {
- *              this.limit = limit;
- *              this.style = style;
- *          }
- *      }
- *
- *      static class Bounds {
- *          int start;
- *          int limit;
- *
- *          public Bounds(int start, int limit) {
- *              this.start = start;
- *              this.limit = limit;
- *          }
- *      }
- *
- *      static int getTextWidth(String text, int start, int limit,
- *                              StyleRun[] styleRuns, int styleRunCount) {
- *          // simplistic way to compute the width
- *          return limit - start;
- *      }
- *
- *      // set limit and StyleRun limit for a line
- *      // from text[start] and from styleRuns[styleRunStart]
- *      // using Bidi.getLogicalRun(...)
- *      // returns line width
- *      static int getLineBreak(String text, Bounds line, Bidi para,
- *                              StyleRun styleRuns[], Bounds styleRun) {
- *          // dummy return
- *          return 0;
- *      }
- *
- *      // render runs on a line sequentially, always from left to right
- *
- *      // prepare rendering a new line
- *      static void startLine(byte textDirection, int lineWidth) {
- *          System.out.println();
- *      }
- *
- *      // render a run of text and advance to the right by the run width
- *      // the text[start..limit-1] is always in logical order
- *      static void renderRun(String text, int start, int limit,
- *                            byte textDirection, int style) {
- *      }
- *
- *      // We could compute a cross-product
- *      // from the style runs with the directional runs
- *      // and then reorder it.
- *      // Instead, here we iterate over each run type
- *      // and render the intersections -
- *      // with shortcuts in simple (and common) cases.
- *      // renderParagraph() is the main function.
- *
- *      // render a directional run with
- *      // (possibly) multiple style runs intersecting with it
- *      static void renderDirectionalRun(String text, int start, int limit,
- *                                       byte direction, StyleRun styleRuns[],
- *                                       int styleRunCount) {
- *          int i;
- *
- *          // iterate over style runs
- *          if (direction == Bidi.LTR) {
- *              int styleLimit;
- *              for (i = 0; i < styleRunCount; ++i) {
- *                  styleLimit = styleRuns[i].limit;
- *                  if (start < styleLimit) {
- *                      if (styleLimit > limit) {
- *                          styleLimit = limit;
- *                      }
- *                      renderRun(text, start, styleLimit,
- *                                direction, styleRuns[i].style);
- *                      if (styleLimit == limit) {
- *                          break;
- *                      }
- *                      start = styleLimit;
- *                  }
- *              }
- *          } else {
- *              int styleStart;
- *
- *              for (i = styleRunCount-1; i >= 0; --i) {
- *                  if (i > 0) {
- *                      styleStart = styleRuns[i-1].limit;
- *                  } else {
- *                      styleStart = 0;
- *                  }
- *                  if (limit >= styleStart) {
- *                      if (styleStart < start) {
- *                          styleStart = start;
- *                      }
- *                      renderRun(text, styleStart, limit, direction,
- *                                styleRuns[i].style);
- *                      if (styleStart == start) {
- *                          break;
- *                      }
- *                      limit = styleStart;
- *                  }
- *              }
- *          }
- *      }
- *
- *      // the line object represents text[start..limit-1]
- *      static void renderLine(Bidi line, String text, int start, int limit,
- *                             StyleRun styleRuns[], int styleRunCount) {
- *          byte direction = line.getDirection();
- *          if (direction != Bidi.MIXED) {
- *              // unidirectional
- *              if (styleRunCount <= 1) {
- *                  renderRun(text, start, limit, direction, styleRuns[0].style);
- *              } else {
- *                  renderDirectionalRun(text, start, limit, direction,
- *                                       styleRuns, styleRunCount);
- *              }
- *          } else {
- *              // mixed-directional
- *              int count, i;
- *              BidiRun run;
- *
- *              try {
- *                  count = line.countRuns();
- *              } catch (IllegalStateException e) {
- *                  e.printStackTrace();
- *                  return;
- *              }
- *              if (styleRunCount <= 1) {
- *                  int style = styleRuns[0].style;
- *
- *                  // iterate over directional runs
- *                  for (i = 0; i < count; ++i) {
- *                      run = line.getVisualRun(i);
- *                      renderRun(text, run.getStart(), run.getLimit(),
- *                                run.getDirection(), style);
- *                  }
- *              } else {
- *                  // iterate over both directional and style runs
- *                  for (i = 0; i < count; ++i) {
- *                      run = line.getVisualRun(i);
- *                      renderDirectionalRun(text, run.getStart(),
- *                                           run.getLimit(), run.getDirection(),
- *                                           styleRuns, styleRunCount);
- *                  }
- *              }
- *          }
- *      }
- *
- *      static void renderParagraph(String text, byte textDirection,
- *                                  StyleRun styleRuns[], int styleRunCount,
- *                                  int lineWidth) {
- *          int length = text.length();
- *          Bidi para = new Bidi();
- *          try {
- *              para.setPara(text,
- *                           textDirection != 0 ? Bidi.LEVEL_DEFAULT_RTL
- *                                              : Bidi.LEVEL_DEFAULT_LTR,
- *                           null);
- *          } catch (Exception e) {
- *              e.printStackTrace();
- *              return;
- *          }
- *          byte paraLevel = (byte)(1 & para.getParaLevel());
- *          StyleRun styleRun = new StyleRun(length, styleNormal);
- *
- *          if (styleRuns == null || styleRunCount <= 0) {
- *              styleRuns = new StyleRun[1];
- *              styleRunCount = 1;
- *              styleRuns[0] = styleRun;
- *          }
- *          // assume styleRuns[styleRunCount-1].limit>=length
- *
- *          int width = getTextWidth(text, 0, length, styleRuns, styleRunCount);
- *          if (width <= lineWidth) {
- *              // everything fits onto one line
- *
- *              // prepare rendering a new line from either left or right
- *              startLine(paraLevel, width);
- *
- *              renderLine(para, text, 0, length, styleRuns, styleRunCount);
- *          } else {
- *              // we need to render several lines
- *              Bidi line = new Bidi(length, 0);
- *              int start = 0, limit;
- *              int styleRunStart = 0, styleRunLimit;
- *
- *              for (;;) {
- *                  limit = length;
- *                  styleRunLimit = styleRunCount;
- *                  width = getLineBreak(text, new Bounds(start, limit),
- *                                       para, styleRuns,
- *                                       new Bounds(styleRunStart, styleRunLimit));
- *                  try {
- *                      line = para.setLine(start, limit);
- *                  } catch (Exception e) {
- *                      e.printStackTrace();
- *                      return;
- *                  }
- *                  // prepare rendering a new line
- *                  // from either left or right
- *                  startLine(paraLevel, width);
- *
- *                  if (styleRunStart > 0) {
- *                      int newRunCount = styleRuns.length - styleRunStart;
- *                      StyleRun[] newRuns = new StyleRun[newRunCount];
- *                      System.arraycopy(styleRuns, styleRunStart, newRuns, 0,
- *                                       newRunCount);
- *                      renderLine(line, text, start, limit, newRuns,
- *                                 styleRunLimit - styleRunStart);
- *                  } else {
- *                      renderLine(line, text, start, limit, styleRuns,
- *                                 styleRunLimit - styleRunStart);
- *                  }
- *                  if (limit == length) {
- *                      break;
- *                  }
- *                  start = limit;
- *                  styleRunStart = styleRunLimit - 1;
- *                  if (start >= styleRuns[styleRunStart].limit) {
- *                      ++styleRunStart;
- *                  }
- *              }
- *          }
- *      }
- *
- *      public static void main(String[] args)
- *      {
- *          renderParagraph("Some Latin text...", Bidi.LTR, null, 0, 80);
- *          renderParagraph("Some Hebrew text...", Bidi.RTL, null, 0, 60);
- *      }
- *  }
- *
- * </pre>
- */
-
-public class Bidi {
-
-    private java.text.Bidi bidi;
-
-    private Bidi(java.text.Bidi delegate) {
-        this.bidi = delegate;
-    }
-
-    /** Paragraph level setting<p>
-     *
-     * Constant indicating that the base direction depends on the first strong
-     * directional character in the text according to the Unicode Bidirectional
-     * Algorithm. If no strong directional character is present,
-     * then set the paragraph level to 0 (left-to-right).<p>
-     *
-     * If this value is used in conjunction with reordering modes
-     * <code>REORDER_INVERSE_LIKE_DIRECT</code> or
-     * <code>REORDER_INVERSE_FOR_NUMBERS_SPECIAL</code>, the text to reorder
-     * is assumed to be visual LTR, and the text after reordering is required
-     * to be the corresponding logical string with appropriate contextual
-     * direction. The direction of the result string will be RTL if either
-     * the righmost or leftmost strong character of the source text is RTL
-     * or Arabic Letter, the direction will be LTR otherwise.<p>
-     *
-     * If reordering option <code>OPTION_INSERT_MARKS</code> is set, an RLM may
-     * be added at the beginning of the result string to ensure round trip
-     * (that the result string, when reordered back to visual, will produce
-     * the original source text).
-     * @see #REORDER_INVERSE_LIKE_DIRECT
-     * @see #REORDER_INVERSE_FOR_NUMBERS_SPECIAL
-     * @stable ICU 3.8
-     */
-    public static final byte LEVEL_DEFAULT_LTR = (byte)0x7e;
-
-    /** Paragraph level setting<p>
-     *
-     * Constant indicating that the base direction depends on the first strong
-     * directional character in the text according to the Unicode Bidirectional
-     * Algorithm. If no strong directional character is present,
-     * then set the paragraph level to 1 (right-to-left).<p>
-     *
-     * If this value is used in conjunction with reordering modes
-     * <code>REORDER_INVERSE_LIKE_DIRECT</code> or
-     * <code>REORDER_INVERSE_FOR_NUMBERS_SPECIAL</code>, the text to reorder
-     * is assumed to be visual LTR, and the text after reordering is required
-     * to be the corresponding logical string with appropriate contextual
-     * direction. The direction of the result string will be RTL if either
-     * the righmost or leftmost strong character of the source text is RTL
-     * or Arabic Letter, or if the text contains no strong character;
-     * the direction will be LTR otherwise.<p>
-     *
-     * If reordering option <code>OPTION_INSERT_MARKS</code> is set, an RLM may
-     * be added at the beginning of the result string to ensure round trip
-     * (that the result string, when reordered back to visual, will produce
-     * the original source text).
-     * @see #REORDER_INVERSE_LIKE_DIRECT
-     * @see #REORDER_INVERSE_FOR_NUMBERS_SPECIAL
-     * @stable ICU 3.8
-     */
-    public static final byte LEVEL_DEFAULT_RTL = (byte)0x7f;
-
-    /**
-     * Maximum explicit embedding level.
-     * (The maximum resolved level can be up to <code>MAX_EXPLICIT_LEVEL+1</code>).
-     * @stable ICU 3.8
-     */
-    public static final byte MAX_EXPLICIT_LEVEL = 61;
-
-    /**
-     * Bit flag for level input.
-     * Overrides directional properties.
-     * @stable ICU 3.8
-     */
-    public static final byte LEVEL_OVERRIDE = (byte)0x80;
-
-    /**
-     * Special value which can be returned by the mapping methods when a
-     * logical index has no corresponding visual index or vice-versa. This may
-     * happen for the logical-to-visual mapping of a Bidi control when option
-     * <code>OPTION_REMOVE_CONTROLS</code> is
-     * specified. This can also happen for the visual-to-logical mapping of a
-     * Bidi mark (LRM or RLM) inserted by option
-     * <code>OPTION_INSERT_MARKS</code>.
-     * @see #getVisualIndex
-     * @see #getVisualMap
-     * @see #getLogicalIndex
-     * @see #getLogicalMap
-     * @see #OPTION_INSERT_MARKS
-     * @see #OPTION_REMOVE_CONTROLS
-     * @stable ICU 3.8
-     */
-    public static final int MAP_NOWHERE = -1;
-
-    /**
-     * All left-to-right text.
-     * @stable ICU 3.8
-     */
-    public static final byte LTR = 0;
-
-    /**
-     * All right-to-left text.
-     * @stable ICU 3.8
-     */
-    public static final byte RTL = 1;
-
-    /**
-     * Mixed-directional text.
-     * @stable ICU 3.8
-     */
-    public static final byte MIXED = 2;
-
-    /**
-     * option bit for writeReordered():
-     * keep combining characters after their base characters in RTL runs
-     *
-     * @see #writeReordered
-     * @stable ICU 3.8
-     */
-    public static final short KEEP_BASE_COMBINING = 1;
-
-    /**
-     * option bit for writeReordered():
-     * replace characters with the "mirrored" property in RTL runs
-     * by their mirror-image mappings
-     *
-     * @see #writeReordered
-     * @stable ICU 3.8
-     */
-    public static final short DO_MIRRORING = 2;
-
-    /**
-     * option bit for writeReordered():
-     * surround the run with LRMs if necessary;
-     * this is part of the approximate "inverse Bidi" algorithm
-     *
-     * <p>This option does not imply corresponding adjustment of the index
-     * mappings.</p>
-     *
-     * @see #setInverse
-     * @see #writeReordered
-     * @stable ICU 3.8
-     */
-    public static final short INSERT_LRM_FOR_NUMERIC = 4;
-
-    /**
-     * option bit for writeReordered():
-     * remove Bidi control characters
-     * (this does not affect INSERT_LRM_FOR_NUMERIC)
-     *
-     * <p>This option does not imply corresponding adjustment of the index
-     * mappings.</p>
-     *
-     * @see #writeReordered
-     * @see #INSERT_LRM_FOR_NUMERIC
-     * @stable ICU 3.8
-     */
-    public static final short REMOVE_BIDI_CONTROLS = 8;
-
-    /**
-     * option bit for writeReordered():
-     * write the output in reverse order
-     *
-     * <p>This has the same effect as calling <code>writeReordered()</code>
-     * first without this option, and then calling
-     * <code>writeReverse()</code> without mirroring.
-     * Doing this in the same step is faster and avoids a temporary buffer.
-     * An example for using this option is output to a character terminal that
-     * is designed for RTL scripts and stores text in reverse order.</p>
-     *
-     * @see #writeReordered
-     * @stable ICU 3.8
-     */
-    public static final short OUTPUT_REVERSE = 16;
-
-    /** Reordering mode: Regular Logical to Visual Bidi algorithm according to Unicode.
-     * @see #setReorderingMode
-     * @stable ICU 3.8
-     */
-    public static final short REORDER_DEFAULT = 0;
-
-    /** Reordering mode: Logical to Visual algorithm which handles numbers in
-     * a way which mimicks the behavior of Windows XP.
-     * @see #setReorderingMode
-     * @stable ICU 3.8
-     */
-    public static final short REORDER_NUMBERS_SPECIAL = 1;
-
-    /** Reordering mode: Logical to Visual algorithm grouping numbers with
-     * adjacent R characters (reversible algorithm).
-     * @see #setReorderingMode
-     * @stable ICU 3.8
-     */
-    public static final short REORDER_GROUP_NUMBERS_WITH_R = 2;
-
-    /** Reordering mode: Reorder runs only to transform a Logical LTR string
-     * to the logical RTL string with the same display, or vice-versa.<br>
-     * If this mode is set together with option
-     * <code>OPTION_INSERT_MARKS</code>, some Bidi controls in the source
-     * text may be removed and other controls may be added to produce the
-     * minimum combination which has the required display.
-     * @see #OPTION_INSERT_MARKS
-     * @see #setReorderingMode
-     * @stable ICU 3.8
-     */
-    public static final short REORDER_RUNS_ONLY = 3;
-
-    /** Reordering mode: Visual to Logical algorithm which handles numbers
-     * like L (same algorithm as selected by <code>setInverse(true)</code>.
-     * @see #setInverse
-     * @see #setReorderingMode
-     * @stable ICU 3.8
-     */
-    public static final short REORDER_INVERSE_NUMBERS_AS_L = 4;
-
-    /** Reordering mode: Visual to Logical algorithm equivalent to the regular
-     * Logical to Visual algorithm.
-     * @see #setReorderingMode
-     * @stable ICU 3.8
-     */
-    public static final short REORDER_INVERSE_LIKE_DIRECT = 5;
-
-    /** Reordering mode: Inverse Bidi (Visual to Logical) algorithm for the
-     * <code>REORDER_NUMBERS_SPECIAL</code> Bidi algorithm.
-     * @see #setReorderingMode
-     * @stable ICU 3.8
-     */
-    public static final short REORDER_INVERSE_FOR_NUMBERS_SPECIAL = 6;
-
-    /**
-     * Option value for <code>setReorderingOptions</code>:
-     * disable all the options which can be set with this method
-     * @see #setReorderingOptions
-     * @stable ICU 3.8
-     */
-    public static final int OPTION_DEFAULT = 0;
-
-    /**
-     * Option bit for <code>setReorderingOptions</code>:
-     * insert Bidi marks (LRM or RLM) when needed to ensure correct result of
-     * a reordering to a Logical order
-     *
-     * <p>This option must be set or reset before calling
-     * <code>setPara</code>.</p>
-     *
-     * <p>This option is significant only with reordering modes which generate
-     * a result with Logical order, specifically.</p>
-     * <ul>
-     *   <li><code>REORDER_RUNS_ONLY</code></li>
-     *   <li><code>REORDER_INVERSE_NUMBERS_AS_L</code></li>
-     *   <li><code>REORDER_INVERSE_LIKE_DIRECT</code></li>
-     *   <li><code>REORDER_INVERSE_FOR_NUMBERS_SPECIAL</code></li>
-     * </ul>
-     *
-     * <p>If this option is set in conjunction with reordering mode
-     * <code>REORDER_INVERSE_NUMBERS_AS_L</code> or with calling
-     * <code>setInverse(true)</code>, it implies option
-     * <code>INSERT_LRM_FOR_NUMERIC</code> in calls to method
-     * <code>writeReordered()</code>.</p>
-     *
-     * <p>For other reordering modes, a minimum number of LRM or RLM characters
-     * will be added to the source text after reordering it so as to ensure
-     * round trip, i.e. when applying the inverse reordering mode on the
-     * resulting logical text with removal of Bidi marks
-     * (option <code>OPTION_REMOVE_CONTROLS</code> set before calling
-     * <code>setPara()</code> or option
-     * <code>REMOVE_BIDI_CONTROLS</code> in
-     * <code>writeReordered</code>), the result will be identical to the
-     * source text in the first transformation.
-     *
-     * <p>This option will be ignored if specified together with option
-     * <code>OPTION_REMOVE_CONTROLS</code>. It inhibits option
-     * <code>REMOVE_BIDI_CONTROLS</code> in calls to method
-     * <code>writeReordered()</code> and it implies option
-     * <code>INSERT_LRM_FOR_NUMERIC</code> in calls to method
-     * <code>writeReordered()</code> if the reordering mode is
-     * <code>REORDER_INVERSE_NUMBERS_AS_L</code>.</p>
-     *
-     * @see #setReorderingMode
-     * @see #setReorderingOptions
-     * @see #INSERT_LRM_FOR_NUMERIC
-     * @see #REMOVE_BIDI_CONTROLS
-     * @see #OPTION_REMOVE_CONTROLS
-     * @see #REORDER_RUNS_ONLY
-     * @see #REORDER_INVERSE_NUMBERS_AS_L
-     * @see #REORDER_INVERSE_LIKE_DIRECT
-     * @see #REORDER_INVERSE_FOR_NUMBERS_SPECIAL
-     * @stable ICU 3.8
-     */
-    public static final int OPTION_INSERT_MARKS = 1;
-
-    /**
-     * Option bit for <code>setReorderingOptions</code>:
-     * remove Bidi control characters
-     *
-     * <p>This option must be set or reset before calling
-     * <code>setPara</code>.</p>
-     *
-     * <p>This option nullifies option
-     * <code>OPTION_INSERT_MARKS</code>. It inhibits option
-     * <code>INSERT_LRM_FOR_NUMERIC</code> in calls to method
-     * <code>writeReordered()</code> and it implies option
-     * <code>REMOVE_BIDI_CONTROLS</code> in calls to that method.</p>
-     *
-     * @see #setReorderingMode
-     * @see #setReorderingOptions
-     * @see #OPTION_INSERT_MARKS
-     * @see #INSERT_LRM_FOR_NUMERIC
-     * @see #REMOVE_BIDI_CONTROLS
-     * @stable ICU 3.8
-     */
-    public static final int OPTION_REMOVE_CONTROLS = 2;
-
-    /**
-     * Option bit for <code>setReorderingOptions</code>:
-     * process the output as part of a stream to be continued
-     *
-     * <p>This option must be set or reset before calling
-     * <code>setPara</code>.</p>
-     *
-     * <p>This option specifies that the caller is interested in processing
-     * large text object in parts. The results of the successive calls are
-     * expected to be concatenated by the caller. Only the call for the last
-     * part will have this option bit off.</p>
-     *
-     * <p>When this option bit is on, <code>setPara()</code> may process
-     * less than the full source text in order to truncate the text at a
-     * meaningful boundary. The caller should call
-     * <code>getProcessedLength()</code> immediately after calling
-     * <code>setPara()</code> in order to determine how much of the source
-     * text has been processed. Source text beyond that length should be
-     * resubmitted in following calls to <code>setPara</code>. The
-     * processed length may be less than the length of the source text if a
-     * character preceding the last character of the source text constitutes a
-     * reasonable boundary (like a block separator) for text to be continued.<br>
-     * If the last character of the source text constitutes a reasonable
-     * boundary, the whole text will be processed at once.<br>
-     * If nowhere in the source text there exists
-     * such a reasonable boundary, the processed length will be zero.<br>
-     * The caller should check for such an occurrence and do one of the following:
-     * <ul><li>submit a larger amount of text with a better chance to include
-     *         a reasonable boundary.</li>
-     *     <li>resubmit the same text after turning off option
-     *         <code>OPTION_STREAMING</code>.</li></ul>
-     * In all cases, this option should be turned off before processing the last
-     * part of the text.</p>
-     *
-     * <p>When the <code>OPTION_STREAMING</code> option is used, it is
-     * recommended to call <code>orderParagraphsLTR(true)</code> before calling
-     * <code>setPara()</code> so that later paragraphs may be concatenated to
-     * previous paragraphs on the right.
-     * </p>
-     *
-     * @see #setReorderingMode
-     * @see #setReorderingOptions
-     * @see #getProcessedLength
-     * @stable ICU 3.8
-     */
-    public static final int OPTION_STREAMING = 4;
-
-    /**
-     * Value returned by <code>BidiClassifier</code> when there is no need to
-     * override the standard Bidi class for a given code point.
-     * @see BidiClassifier
-     * @stable ICU 3.8
-     */
-    public static final int CLASS_DEFAULT = 19; //UCharacterDirection.CHAR_DIRECTION_COUNT;
-
-//    /**
-//     * Allocate a <code>Bidi</code> object.
-//     * Such an object is initially empty. It is assigned
-//     * the Bidi properties of a piece of text containing one or more paragraphs
-//     * by <code>setPara()</code>
-//     * or the Bidi properties of a line within a paragraph by
-//     * <code>setLine()</code>.<p>
-//     * This object can be reused.<p>
-//     * <code>setPara()</code> and <code>setLine()</code> will allocate
-//     * additional memory for internal structures as necessary.
-//     *
-//     * @stable ICU 3.8
-//     */
-//    public Bidi()
-//    {
-//        throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Allocate a <code>Bidi</code> object with preallocated memory
-//     * for internal structures.
-//     * This method provides a <code>Bidi</code> object like the default constructor
-//     * but it also preallocates memory for internal structures
-//     * according to the sizings supplied by the caller.<p>
-//     * The preallocation can be limited to some of the internal memory
-//     * by setting some values to 0 here. That means that if, e.g.,
-//     * <code>maxRunCount</code> cannot be reasonably predetermined and should not
-//     * be set to <code>maxLength</code> (the only failproof value) to avoid
-//     * wasting  memory, then <code>maxRunCount</code> could be set to 0 here
-//     * and the internal structures that are associated with it will be allocated
-//     * on demand, just like with the default constructor.
-//     *
-//     * @param maxLength is the maximum text or line length that internal memory
-//     *        will be preallocated for. An attempt to associate this object with a
-//     *        longer text will fail, unless this value is 0, which leaves the allocation
-//     *        up to the implementation.
-//     *
-//     * @param maxRunCount is the maximum anticipated number of same-level runs
-//     *        that internal memory will be preallocated for. An attempt to access
-//     *        visual runs on an object that was not preallocated for as many runs
-//     *        as the text was actually resolved to will fail,
-//     *        unless this value is 0, which leaves the allocation up to the implementation.<br><br>
-//     *        The number of runs depends on the actual text and maybe anywhere between
-//     *        1 and <code>maxLength</code>. It is typically small.
-//     *
-//     * @throws IllegalArgumentException if maxLength or maxRunCount is less than 0
-//     * @stable ICU 3.8
-//     */
-//    public Bidi(int maxLength, int maxRunCount)
-//    {
-//        throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Modify the operation of the Bidi algorithm such that it
-//     * approximates an "inverse Bidi" algorithm. This method
-//     * must be called before <code>setPara()</code>.
-//     *
-//     * <p>The normal operation of the Bidi algorithm as described
-//     * in the Unicode Technical Report is to take text stored in logical
-//     * (keyboard, typing) order and to determine the reordering of it for visual
-//     * rendering.
-//     * Some legacy systems store text in visual order, and for operations
-//     * with standard, Unicode-based algorithms, the text needs to be transformed
-//     * to logical order. This is effectively the inverse algorithm of the
-//     * described Bidi algorithm. Note that there is no standard algorithm for
-//     * this "inverse Bidi" and that the current implementation provides only an
-//     * approximation of "inverse Bidi".</p>
-//     *
-//     * <p>With <code>isInversed</code> set to <code>true</code>,
-//     * this method changes the behavior of some of the subsequent methods
-//     * in a way that they can be used for the inverse Bidi algorithm.
-//     * Specifically, runs of text with numeric characters will be treated in a
-//     * special way and may need to be surrounded with LRM characters when they are
-//     * written in reordered sequence.</p>
-//     *
-//     * <p>Output runs should be retrieved using <code>getVisualRun()</code>.
-//     * Since the actual input for "inverse Bidi" is visually ordered text and
-//     * <code>getVisualRun()</code> gets the reordered runs, these are actually
-//     * the runs of the logically ordered output.</p>
-//     *
-//     * <p>Calling this method with argument <code>isInverse</code> set to
-//     * <code>true</code> is equivalent to calling <code>setReorderingMode</code>
-//     * with argument <code>reorderingMode</code>
-//     * set to <code>REORDER_INVERSE_NUMBERS_AS_L</code>.<br>
-//     * Calling this method with argument <code>isInverse</code> set to
-//     * <code>false</code> is equivalent to calling <code>setReorderingMode</code>
-//     * with argument <code>reorderingMode</code>
-//     * set to <code>REORDER_DEFAULT</code>.
-//     *
-//     * @param isInverse specifies "forward" or "inverse" Bidi operation.
-//     *
-//     * @see #setPara
-//     * @see #writeReordered
-//     * @see #setReorderingMode
-//     * @see #REORDER_INVERSE_NUMBERS_AS_L
-//     * @see #REORDER_DEFAULT
-//     * @stable ICU 3.8
-//     */
-//    public void setInverse(boolean isInverse) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Is this <code>Bidi</code> object set to perform the inverse Bidi
-//     * algorithm?
-//     * <p>Note: calling this method after setting the reordering mode with
-//     * <code>setReorderingMode</code> will return <code>true</code> if the
-//     * reordering mode was set to
-//     * <code>REORDER_INVERSE_NUMBERS_AS_L<code>, <code>false</code>
-//     * for all other values.</p>
-//     *
-//     * @return <code>true</code> if the <code>Bidi</code> object is set to
-//     * perform the inverse Bidi algorithm by handling numbers as L.
-//     *
-//     * @see #setInverse
-//     * @see #setReorderingMode
-//     * @see #REORDER_INVERSE_NUMBERS_AS_L
-//     * @stable ICU 3.8
-//     */
-//    public boolean isInverse() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Modify the operation of the Bidi algorithm such that it implements some
-//     * variant to the basic Bidi algorithm or approximates an "inverse Bidi"
-//     * algorithm, depending on different values of the "reordering mode".
-//     * This method must be called before <code>setPara()</code>, and stays in
-//     * effect until called again with a different argument.
-//     *
-//     * <p>The normal operation of the Bidi algorithm as described in the Unicode
-//     * Standard Annex #9 is to take text stored in logical (keyboard, typing)
-//     * order and to determine how to reorder it for visual rendering.</p>
-//     *
-//     * <p>With the reordering mode set to a value other than
-//     * <code>REORDER_DEFAULT</code>, this method changes the behavior of some of
-//     * the subsequent methods in a way such that they implement an inverse Bidi
-//     * algorithm or some other algorithm variants.</p>
-//     *
-//     * <p>Some legacy systems store text in visual order, and for operations
-//     * with standard, Unicode-based algorithms, the text needs to be transformed
-//     * into logical order. This is effectively the inverse algorithm of the
-//     * described Bidi algorithm. Note that there is no standard algorithm for
-//     * this "inverse Bidi", so a number of variants are implemented here.</p>
-//     *
-//     * <p>In other cases, it may be desirable to emulate some variant of the
-//     * Logical to Visual algorithm (e.g. one used in MS Windows), or perform a
-//     * Logical to Logical transformation.</p>
-//     *
-//     * <ul>
-//     * <li>When the Reordering Mode is set to
-//     * <code>REORDER_DEFAULT</code>,
-//     * the standard Bidi Logical to Visual algorithm is applied.</li>
-//     *
-//     * <li>When the reordering mode is set to
-//     * <code>REORDER_NUMBERS_SPECIAL</code>,
-//     * the algorithm used to perform Bidi transformations when calling
-//     * <code>setPara</code> should approximate the algorithm used in Microsoft
-//     * Windows XP rather than strictly conform to the Unicode Bidi algorithm.
-//     * <br>
-//     * The differences between the basic algorithm and the algorithm addressed
-//     * by this option are as follows:
-//     * <ul>
-//     *   <li>Within text at an even embedding level, the sequence "123AB"
-//     *   (where AB represent R or AL letters) is transformed to "123BA" by the
-//     *   Unicode algorithm and to "BA123" by the Windows algorithm.</li>
-//     *
-//     *   <li>Arabic-Indic numbers (AN) are handled by the Windows algorithm just
-//     *   like regular numbers (EN).</li>
-//     * </ul></li>
-//     *
-//     * <li>When the reordering mode is set to
-//     * <code>REORDER_GROUP_NUMBERS_WITH_R</code>,
-//     * numbers located between LTR text and RTL text are associated with the RTL
-//     * text. For instance, an LTR paragraph with content "abc 123 DEF" (where
-//     * upper case letters represent RTL characters) will be transformed to
-//     * "abc FED 123" (and not "abc 123 FED"), "DEF 123 abc" will be transformed
-//     * to "123 FED abc" and "123 FED abc" will be transformed to "DEF 123 abc".
-//     * This makes the algorithm reversible and makes it useful when round trip
-//     * (from visual to logical and back to visual) must be achieved without
-//     * adding LRM characters. However, this is a variation from the standard
-//     * Unicode Bidi algorithm.<br>
-//     * The source text should not contain Bidi control characters other than LRM
-//     * or RLM.</li>
-//     *
-//     * <li>When the reordering mode is set to
-//     * <code>REORDER_RUNS_ONLY</code>,
-//     * a "Logical to Logical" transformation must be performed:
-//     * <ul>
-//     * <li>If the default text level of the source text (argument
-//     * <code>paraLevel</code> in <code>setPara</code>) is even, the source text
-//     * will be handled as LTR logical text and will be transformed to the RTL
-//     * logical text which has the same LTR visual display.</li>
-//     * <li>If the default level of the source text is odd, the source text
-//     * will be handled as RTL logical text and will be transformed to the
-//     * LTR logical text which has the same LTR visual display.</li>
-//     * </ul>
-//     * This mode may be needed when logical text which is basically Arabic or
-//     * Hebrew, with possible included numbers or phrases in English, has to be
-//     * displayed as if it had an even embedding level (this can happen if the
-//     * displaying application treats all text as if it was basically LTR).
-//     * <br>
-//     * This mode may also be needed in the reverse case, when logical text which
-//     * is basically English, with possible included phrases in Arabic or Hebrew,
-//     * has to be displayed as if it had an odd embedding level.
-//     * <br>
-//     * Both cases could be handled by adding LRE or RLE at the head of the
-//     * text, if the display subsystem supports these formatting controls. If it
-//     * does not, the problem may be handled by transforming the source text in
-//     * this mode before displaying it, so that it will be displayed properly.
-//     * <br>
-//     * The source text should not contain Bidi control characters other than LRM
-//     * or RLM.</li>
-//     *
-//     * <li>When the reordering mode is set to
-//     * <code>REORDER_INVERSE_NUMBERS_AS_L</code>, an "inverse Bidi"
-//     * algorithm is applied.
-//     * Runs of text with numeric characters will be treated like LTR letters and
-//     * may need to be surrounded with LRM characters when they are written in
-//     * reordered sequence (the option <code>INSERT_LRM_FOR_NUMERIC</code> can
-//     * be used with method <code>writeReordered</code> to this end. This mode
-//     * is equivalent to calling <code>setInverse()</code> with
-//     * argument <code>isInverse</code> set to <code>true</code>.</li>
-//     *
-//     * <li>When the reordering mode is set to
-//     * <code>REORDER_INVERSE_LIKE_DIRECT</code>, the "direct" Logical to
-//     * Visual Bidi algorithm is used as an approximation of an "inverse Bidi"
-//     * algorithm. This mode is similar to mode
-//     * <code>REORDER_INVERSE_NUMBERS_AS_L</code> but is closer to the
-//     * regular Bidi algorithm.
-//     * <br>
-//     * For example, an LTR paragraph with the content "FED 123 456 CBA" (where
-//     * upper case represents RTL characters) will be transformed to
-//     * "ABC 456 123 DEF", as opposed to "DEF 123 456 ABC"
-//     * with mode <code>REORDER_INVERSE_NUMBERS_AS_L</code>.<br>
-//     * When used in conjunction with option
-//     * <code>OPTION_INSERT_MARKS</code>, this mode generally
-//     * adds Bidi marks to the output significantly more sparingly than mode
-//     * <code>REORDER_INVERSE_NUMBERS_AS_L</code>.<br> with option
-//     * <code>INSERT_LRM_FOR_NUMERIC</code> in calls to
-//     * <code>writeReordered</code>.</li>
-//     *
-//     * <li>When the reordering mode is set to
-//     * <code>REORDER_INVERSE_FOR_NUMBERS_SPECIAL</code>, the Logical to Visual
-//     * Bidi algorithm used in Windows XP is used as an approximation of an "inverse
-//     * Bidi" algorithm.
-//     * <br>
-//     * For example, an LTR paragraph with the content "abc FED123" (where
-//     * upper case represents RTL characters) will be transformed to
-//     * "abc 123DEF.</li>
-//     * </ul>
-//     *
-//     * <p>In all the reordering modes specifying an "inverse Bidi" algorithm
-//     * (i.e. those with a name starting with <code>REORDER_INVERSE</code>),
-//     * output runs should be retrieved using <code>getVisualRun()</code>, and
-//     * the output text with <code>writeReordered()</code>. The caller should
-//     * keep in mind that in "inverse Bidi" modes the input is actually visually
-//     * ordered text and reordered output returned by <code>getVisualRun()</code>
-//     * or <code>writeReordered()</code> are actually runs or character string
-//     * of logically ordered output.<br>
-//     * For all the "inverse Bidi" modes, the source text should not contain
-//     * Bidi control characters other than LRM or RLM.</p>
-//     *
-//     * <p>Note that option <code>OUTPUT_REVERSE</code> of
-//     * <code>writeReordered</code> has no useful meaning and should not be used
-//     * in conjunction with any value of the reordering mode specifying "inverse
-//     * Bidi" or with value <code>REORDER_RUNS_ONLY</code>.
-//     *
-//     * @param reorderingMode specifies the required variant of the Bidi
-//     *                       algorithm.
-//     *
-//     * @see #setInverse
-//     * @see #setPara
-//     * @see #writeReordered
-//     * @see #INSERT_LRM_FOR_NUMERIC
-//     * @see #OUTPUT_REVERSE
-//     * @see #REORDER_DEFAULT
-//     * @see #REORDER_NUMBERS_SPECIAL
-//     * @see #REORDER_GROUP_NUMBERS_WITH_R
-//     * @see #REORDER_RUNS_ONLY
-//     * @see #REORDER_INVERSE_NUMBERS_AS_L
-//     * @see #REORDER_INVERSE_LIKE_DIRECT
-//     * @see #REORDER_INVERSE_FOR_NUMBERS_SPECIAL
-//     * @stable ICU 3.8
-//     */
-//    public void setReorderingMode(int reorderingMode) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * What is the requested reordering mode for a given Bidi object?
-//     *
-//     * @return the current reordering mode of the Bidi object
-//     *
-//     * @see #setReorderingMode
-//     * @stable ICU 3.8
-//     */
-//    public int getReorderingMode() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Specify which of the reordering options should be applied during Bidi
-//     * transformations.
-//     *
-//     * @param options A combination of zero or more of the following
-//     * reordering options:
-//     * <code>OPTION_DEFAULT</code>, <code>OPTION_INSERT_MARKS</code>,
-//     * <code>OPTION_REMOVE_CONTROLS</code>, <code>OPTION_STREAMING</code>.
-//     *
-//     * @see #getReorderingOptions
-//     * @see #OPTION_DEFAULT
-//     * @see #OPTION_INSERT_MARKS
-//     * @see #OPTION_REMOVE_CONTROLS
-//     * @see #OPTION_STREAMING
-//     * @stable ICU 3.8
-//     */
-//    public void setReorderingOptions(int options) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * What are the reordering options applied to a given Bidi object?
-//     *
-//     * @return the current reordering options of the Bidi object
-//     *
-//     * @see #setReorderingOptions
-//     * @stable ICU 3.8
-//     */
-//    public int getReorderingOptions() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Perform the Unicode Bidi algorithm. It is defined in the
-//     * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Annex #9</a>,
-//     * version 13,
-//     * also described in The Unicode Standard, Version 4.0 .<p>
-//     *
-//     * This method takes a piece of plain text containing one or more paragraphs,
-//     * with or without externally specified embedding levels from <i>styled</i>
-//     * text and computes the left-right-directionality of each character.<p>
-//     *
-//     * If the entire text is all of the same directionality, then
-//     * the method may not perform all the steps described by the algorithm,
-//     * i.e., some levels may not be the same as if all steps were performed.
-//     * This is not relevant for unidirectional text.<br>
-//     * For example, in pure LTR text with numbers the numbers would get
-//     * a resolved level of 2 higher than the surrounding text according to
-//     * the algorithm. This implementation may set all resolved levels to
-//     * the same value in such a case.<p>
-//     *
-//     * The text can be composed of multiple paragraphs. Occurrence of a block
-//     * separator in the text terminates a paragraph, and whatever comes next starts
-//     * a new paragraph. The exception to this rule is when a Carriage Return (CR)
-//     * is followed by a Line Feed (LF). Both CR and LF are block separators, but
-//     * in that case, the pair of characters is considered as terminating the
-//     * preceding paragraph, and a new paragraph will be started by a character
-//     * coming after the LF.
-//     *
-//     * Although the text is passed here as a <code>String</code>, it is
-//     * stored internally as an array of characters. Therefore the
-//     * documentation will refer to indexes of the characters in the text.
-//     *
-//     * @param text contains the text that the Bidi algorithm will be performed
-//     *        on. This text can be retrieved with <code>getText()</code> or
-//     *        <code>getTextAsString</code>.<br>
-//     *
-//     * @param paraLevel specifies the default level for the text;
-//     *        it is typically 0 (LTR) or 1 (RTL).
-//     *        If the method shall determine the paragraph level from the text,
-//     *        then <code>paraLevel</code> can be set to
-//     *        either <code>LEVEL_DEFAULT_LTR</code>
-//     *        or <code>LEVEL_DEFAULT_RTL</code>; if the text contains multiple
-//     *        paragraphs, the paragraph level shall be determined separately for
-//     *        each paragraph; if a paragraph does not include any strongly typed
-//     *        character, then the desired default is used (0 for LTR or 1 for RTL).
-//     *        Any other value between 0 and <code>MAX_EXPLICIT_LEVEL</code>
-//     *        is also valid, with odd levels indicating RTL.
-//     *
-//     * @param embeddingLevels (in) may be used to preset the embedding and override levels,
-//     *        ignoring characters like LRE and PDF in the text.
-//     *        A level overrides the directional property of its corresponding
-//     *        (same index) character if the level has the
-//     *        <code>LEVEL_OVERRIDE</code> bit set.<br><br>
-//     *        Except for that bit, it must be
-//     *        <code>paraLevel<=embeddingLevels[]<=MAX_EXPLICIT_LEVEL</code>,
-//     *        with one exception: a level of zero may be specified for a
-//     *        paragraph separator even if <code>paraLevel&gt;0</code> when multiple
-//     *        paragraphs are submitted in the same call to <code>setPara()</code>.<br><br>
-//     *        <strong>Caution: </strong>A reference to this array, not a copy
-//     *        of the levels, will be stored in the <code>Bidi</code> object;
-//     *        the <code>embeddingLevels</code>
-//     *        should not be modified to avoid unexpected results on subsequent
-//     *        Bidi operations. However, the <code>setPara()</code> and
-//     *        <code>setLine()</code> methods may modify some or all of the
-//     *        levels.<br><br>
-//     *        <strong>Note:</strong> the <code>embeddingLevels</code> array must
-//     *        have one entry for each character in <code>text</code>.
-//     *
-//     * @throws IllegalArgumentException if the values in embeddingLevels are
-//     *         not within the allowed range
-//     *
-//     * @see #LEVEL_DEFAULT_LTR
-//     * @see #LEVEL_DEFAULT_RTL
-//     * @see #LEVEL_OVERRIDE
-//     * @see #MAX_EXPLICIT_LEVEL
-//     * @stable ICU 3.8
-//     */
-//    public void setPara(String text, byte paraLevel, byte[] embeddingLevels)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Perform the Unicode Bidi algorithm. It is defined in the
-//     * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Annex #9</a>,
-//     * version 13,
-//     * also described in The Unicode Standard, Version 4.0 .<p>
-//     *
-//     * This method takes a piece of plain text containing one or more paragraphs,
-//     * with or without externally specified embedding levels from <i>styled</i>
-//     * text and computes the left-right-directionality of each character.<p>
-//     *
-//     * If the entire text is all of the same directionality, then
-//     * the method may not perform all the steps described by the algorithm,
-//     * i.e., some levels may not be the same as if all steps were performed.
-//     * This is not relevant for unidirectional text.<br>
-//     * For example, in pure LTR text with numbers the numbers would get
-//     * a resolved level of 2 higher than the surrounding text according to
-//     * the algorithm. This implementation may set all resolved levels to
-//     * the same value in such a case.<p>
-//     *
-//     * The text can be composed of multiple paragraphs. Occurrence of a block
-//     * separator in the text terminates a paragraph, and whatever comes next starts
-//     * a new paragraph. The exception to this rule is when a Carriage Return (CR)
-//     * is followed by a Line Feed (LF). Both CR and LF are block separators, but
-//     * in that case, the pair of characters is considered as terminating the
-//     * preceding paragraph, and a new paragraph will be started by a character
-//     * coming after the LF.
-//     *
-//     * The text is stored internally as an array of characters. Therefore the
-//     * documentation will refer to indexes of the characters in the text.
-//     *
-//     * @param chars contains the text that the Bidi algorithm will be performed
-//     *        on. This text can be retrieved with <code>getText()</code> or
-//     *        <code>getTextAsString</code>.<br>
-//     *
-//     * @param paraLevel specifies the default level for the text;
-//     *        it is typically 0 (LTR) or 1 (RTL).
-//     *        If the method shall determine the paragraph level from the text,
-//     *        then <code>paraLevel</code> can be set to
-//     *        either <code>LEVEL_DEFAULT_LTR</code>
-//     *        or <code>LEVEL_DEFAULT_RTL</code>; if the text contains multiple
-//     *        paragraphs, the paragraph level shall be determined separately for
-//     *        each paragraph; if a paragraph does not include any strongly typed
-//     *        character, then the desired default is used (0 for LTR or 1 for RTL).
-//     *        Any other value between 0 and <code>MAX_EXPLICIT_LEVEL</code>
-//     *        is also valid, with odd levels indicating RTL.
-//     *
-//     * @param embeddingLevels (in) may be used to preset the embedding and
-//     *        override levels, ignoring characters like LRE and PDF in the text.
-//     *        A level overrides the directional property of its corresponding
-//     *        (same index) character if the level has the
-//     *        <code>LEVEL_OVERRIDE</code> bit set.<br><br>
-//     *        Except for that bit, it must be
-//     *        <code>paraLevel<=embeddingLevels[]<=MAX_EXPLICIT_LEVEL</code>,
-//     *        with one exception: a level of zero may be specified for a
-//     *        paragraph separator even if <code>paraLevel&gt;0</code> when multiple
-//     *        paragraphs are submitted in the same call to <code>setPara()</code>.<br><br>
-//     *        <strong>Caution: </strong>A reference to this array, not a copy
-//     *        of the levels, will be stored in the <code>Bidi</code> object;
-//     *        the <code>embeddingLevels</code>
-//     *        should not be modified to avoid unexpected results on subsequent
-//     *        Bidi operations. However, the <code>setPara()</code> and
-//     *        <code>setLine()</code> methods may modify some or all of the
-//     *        levels.<br><br>
-//     *        <strong>Note:</strong> the <code>embeddingLevels</code> array must
-//     *        have one entry for each character in <code>text</code>.
-//     *
-//     * @throws IllegalArgumentException if the values in embeddingLevels are
-//     *         not within the allowed range
-//     *
-//     * @see #LEVEL_DEFAULT_LTR
-//     * @see #LEVEL_DEFAULT_RTL
-//     * @see #LEVEL_OVERRIDE
-//     * @see #MAX_EXPLICIT_LEVEL
-//     * @stable ICU 3.8
-//     */
-//    public void setPara(char[] chars, byte paraLevel, byte[] embeddingLevels)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Perform the Unicode Bidi algorithm on a given paragraph, as defined in the
-//     * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Annex #9</a>,
-//     * version 13,
-//     * also described in The Unicode Standard, Version 4.0 .<p>
-//     *
-//     * This method takes a paragraph of text and computes the
-//     * left-right-directionality of each character. The text should not
-//     * contain any Unicode block separators.<p>
-//     *
-//     * The RUN_DIRECTION attribute in the text, if present, determines the base
-//     * direction (left-to-right or right-to-left). If not present, the base
-//     * direction is computed using the Unicode Bidirectional Algorithm,
-//     * defaulting to left-to-right if there are no strong directional characters
-//     * in the text. This attribute, if present, must be applied to all the text
-//     * in the paragraph.<p>
-//     *
-//     * The BIDI_EMBEDDING attribute in the text, if present, represents
-//     * embedding level information. Negative values from -1 to -62 indicate
-//     * overrides at the absolute value of the level. Positive values from 1 to
-//     * 62 indicate embeddings. Where values are zero or not defined, the base
-//     * embedding level as determined by the base direction is assumed.<p>
-//     *
-//     * The NUMERIC_SHAPING attribute in the text, if present, converts European
-//     * digits to other decimal digits before running the bidi algorithm. This
-//     * attribute, if present, must be applied to all the text in the paragraph.
-//     *
-//     * If the entire text is all of the same directionality, then
-//     * the method may not perform all the steps described by the algorithm,
-//     * i.e., some levels may not be the same as if all steps were performed.
-//     * This is not relevant for unidirectional text.<br>
-//     * For example, in pure LTR text with numbers the numbers would get
-//     * a resolved level of 2 higher than the surrounding text according to
-//     * the algorithm. This implementation may set all resolved levels to
-//     * the same value in such a case.<p>
-//     *
-//     * @param paragraph a paragraph of text with optional character and
-//     *        paragraph attribute information
-//     * @stable ICU 3.8
-//     */
-//    public void setPara(AttributedCharacterIterator paragraph)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Specify whether block separators must be allocated level zero,
-//     * so that successive paragraphs will progress from left to right.
-//     * This method must be called before <code>setPara()</code>.
-//     * Paragraph separators (B) may appear in the text.  Setting them to level zero
-//     * means that all paragraph separators (including one possibly appearing
-//     * in the last text position) are kept in the reordered text after the text
-//     * that they follow in the source text.
-//     * When this feature is not enabled, a paragraph separator at the last
-//     * position of the text before reordering will go to the first position
-//     * of the reordered text when the paragraph level is odd.
-//     *
-//     * @param ordarParaLTR specifies whether paragraph separators (B) must
-//     * receive level 0, so that successive paragraphs progress from left to right.
-//     *
-//     * @see #setPara
-//     * @stable ICU 3.8
-//     */
-//    public void orderParagraphsLTR(boolean ordarParaLTR) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Is this <code>Bidi</code> object set to allocate level 0 to block
-//     * separators so that successive paragraphs progress from left to right?
-//     *
-//     * @return <code>true</code> if the <code>Bidi</code> object is set to
-//     *         allocate level 0 to block separators.
-//     *
-//     * @stable ICU 3.8
-//     */
-//    public boolean isOrderParagraphsLTR() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Get the directionality of the text.
-//     *
-//     * @return a value of <code>LTR</code>, <code>RTL</code> or <code>MIXED</code>
-//     *         that indicates if the entire text
-//     *         represented by this object is unidirectional,
-//     *         and which direction, or if it is mixed-directional.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     *
-//     * @see #LTR
-//     * @see #RTL
-//     * @see #MIXED
-//     * @stable ICU 3.8
-//     */
-//    public byte getDirection()
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Get the text.
-//     *
-//     * @return A <code>String</code> containing the text that the
-//     *         <code>Bidi</code> object was created for.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     *
-//     * @see #setPara
-//     * @see #setLine
-//     * @stable ICU 3.8
-//     */
-//    public String getTextAsString()
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Get the text.
-//     *
-//     * @return A <code>char</code> array containing the text that the
-//     *         <code>Bidi</code> object was created for.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     *
-//     * @see #setPara
-//     * @see #setLine
-//     * @stable ICU 3.8
-//     */
-//    public char[] getText()
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Get the length of the text.
-     *
-     * @return The length of the text that the <code>Bidi</code> object was
-     *         created for.
-     *
-     * @throws IllegalStateException if this call is not preceded by a successful
-     *         call to <code>setPara</code> or <code>setLine</code>
-     * @stable ICU 3.8
-     */
-    public int getLength()
-    {
-        return bidi.getLength();
-    }
-
-//    /**
-//     * Get the length of the source text processed by the last call to
-//     * <code>setPara()</code>. This length may be different from the length of
-//     * the source text if option <code>OPTION_STREAMING</code> has been
-//     * set.
-//     * <br>
-//     * Note that whenever the length of the text affects the execution or the
-//     * result of a method, it is the processed length which must be considered,
-//     * except for <code>setPara</code> (which receives unprocessed source text)
-//     * and <code>getLength</code> (which returns the original length of the
-//     * source text).<br>
-//     * In particular, the processed length is the one to consider in the
-//     * following cases:
-//     * <ul>
-//     * <li>maximum value of the <code>limit</code> argument of
-//     * <code>setLine</code></li>
-//     * <li>maximum value of the <code>charIndex</code> argument of
-//     * <code>getParagraph</code></li>
-//     * <li>maximum value of the <code>charIndex</code> argument of
-//     * <code>getLevelAt</code></li>
-//     * <li>number of elements in the array returned by <code>getLevels</code>
-//     * </li>
-//     * <li>maximum value of the <code>logicalStart</code> argument of
-//     * <code>getLogicalRun</code></li>
-//     * <li>maximum value of the <code>logicalIndex</code> argument of
-//     * <code>getVisualIndex</code></li>
-//     * <li>number of elements returned by <code>getLogicalMap</code></li>
-//     * <li>length of text processed by <code>writeReordered</code></li>
-//     * </ul>
-//     *
-//     * @return The length of the part of the source text processed by
-//     *         the last call to <code>setPara</code>.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     *
-//     * @see #setPara
-//     * @see #OPTION_STREAMING
-//     * @stable ICU 3.8
-//     */
-//    public int getProcessedLength() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Get the length of the reordered text resulting from the last call to
-//     * <code>setPara()</code>. This length may be different from the length
-//     * of the source text if option <code>OPTION_INSERT_MARKS</code>
-//     * or option <code>OPTION_REMOVE_CONTROLS</code> has been set.
-//     * <br>
-//     * This resulting length is the one to consider in the following cases:
-//     * <ul>
-//     * <li>maximum value of the <code>visualIndex</code> argument of
-//     * <code>getLogicalIndex</code></li>
-//     * <li>number of elements returned by <code>getVisualMap</code></li>
-//     * </ul>
-//     * Note that this length stays identical to the source text length if
-//     * Bidi marks are inserted or removed using option bits of
-//     * <code>writeReordered</code>, or if option
-//     * <code>REORDER_INVERSE_NUMBERS_AS_L</code> has been set.
-//     *
-//     * @return The length of the reordered text resulting from
-//     *         the last call to <code>setPara</code>.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     *
-//     * @see #setPara
-//     * @see #OPTION_INSERT_MARKS
-//     * @see #OPTION_REMOVE_CONTROLS
-//     * @see #REORDER_INVERSE_NUMBERS_AS_L
-//     * @stable ICU 3.8
-//     */
-//    public int getResultLength() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /* paragraphs API methods ------------------------------------------------- */
-
-//    /**
-//     * Get the paragraph level of the text.
-//     *
-//     * @return The paragraph level. If there are multiple paragraphs, their
-//     *         level may vary if the required paraLevel is LEVEL_DEFAULT_LTR or
-//     *         LEVEL_DEFAULT_RTL.  In that case, the level of the first paragraph
-//     *         is returned.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     *
-//     * @see #LEVEL_DEFAULT_LTR
-//     * @see #LEVEL_DEFAULT_RTL
-//     * @see #getParagraph
-//     * @see #getParagraphByIndex
-//     * @stable ICU 3.8
-//     */
-//    public byte getParaLevel()
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Get the number of paragraphs.
-//     *
-//     * @return The number of paragraphs.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     * @stable ICU 3.8
-//     */
-//    public int countParagraphs()
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Get a paragraph, given the index of this paragraph.
-//     *
-//     * This method returns information about a paragraph.<p>
-//     *
-//     * @param paraIndex is the number of the paragraph, in the
-//     *        range <code>[0..countParagraphs()-1]</code>.
-//     *
-//     * @return a BidiRun object with the details of the paragraph:<br>
-//     *        <code>start</code> will receive the index of the first character
-//     *        of the paragraph in the text.<br>
-//     *        <code>limit</code> will receive the limit of the paragraph.<br>
-//     *        <code>embeddingLevel</code> will receive the level of the paragraph.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     * @throws IllegalArgumentException if paraIndex is not in the range
-//     *        <code>[0..countParagraphs()-1]</code>
-//     *
-//     * @see com.ibm.icu.text.BidiRun
-//     * @stable ICU 3.8
-//     */
-//    public BidiRun getParagraphByIndex(int paraIndex)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Get a paragraph, given a position within the text.
-//     * This method returns information about a paragraph.<br>
-//     * Note: if the paragraph index is known, it is more efficient to
-//     * retrieve the paragraph information using getParagraphByIndex().<p>
-//     *
-//     * @param charIndex is the index of a character within the text, in the
-//     *        range <code>[0..getProcessedLength()-1]</code>.
-//     *
-//     * @return a BidiRun object with the details of the paragraph:<br>
-//     *        <code>start</code> will receive the index of the first character
-//     *        of the paragraph in the text.<br>
-//     *        <code>limit</code> will receive the limit of the paragraph.<br>
-//     *        <code>embeddingLevel</code> will receive the level of the paragraph.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     * @throws IllegalArgumentException if charIndex is not within the legal range
-//     *
-//     * @see com.ibm.icu.text.BidiRun
-//     * @see #getParagraphByIndex
-//     * @see #getProcessedLength
-//     * @stable ICU 3.8
-//     */
-//    public BidiRun getParagraph(int charIndex)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Get the index of a paragraph, given a position within the text.<p>
-//     *
-//     * @param charIndex is the index of a character within the text, in the
-//     *        range <code>[0..getProcessedLength()-1]</code>.
-//     *
-//     * @return The index of the paragraph containing the specified position,
-//     *         starting from 0.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     * @throws IllegalArgumentException if charIndex is not within the legal range
-//     *
-//     * @see com.ibm.icu.text.BidiRun
-//     * @see #getProcessedLength
-//     * @stable ICU 3.8
-//     */
-//    public int getParagraphIndex(int charIndex)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Set a custom Bidi classifier used by the UBA implementation for Bidi
-//     * class determination.
-//     *
-//     * @param classifier A new custom classifier. This can be null.
-//     *
-//     * @see #getCustomClassifier
-//     * @stable ICU 3.8
-//     */
-//    public void setCustomClassifier(BidiClassifier classifier) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Gets the current custom class classifier used for Bidi class
-//     * determination.
-//     *
-//     * @return An instance of class <code>BidiClassifier</code>
-//     *
-//     * @see #setCustomClassifier
-//     * @stable ICU 3.8
-//     */
-//    public BidiClassifier getCustomClassifier() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Retrieves the Bidi class for a given code point.
-//     * <p>If a <code>BidiClassifier</code> is defined and returns a value
-//     * other than <code>CLASS_DEFAULT</code>, that value is used; otherwise
-//     * the default class determination mechanism is invoked.</p>
-//     *
-//     * @param c The code point to get a Bidi class for.
-//     *
-//     * @return The Bidi class for the character <code>c</code> that is in effect
-//     *         for this <code>Bidi</code> instance.
-//     *
-//     * @see BidiClassifier
-//     * @stable ICU 3.8
-//     */
-//    public int getCustomizedClass(int c) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * <code>setLine()</code> returns a <code>Bidi</code> object to
-//     * contain the reordering information, especially the resolved levels,
-//     * for all the characters in a line of text. This line of text is
-//     * specified by referring to a <code>Bidi</code> object representing
-//     * this information for a piece of text containing one or more paragraphs,
-//     * and by specifying a range of indexes in this text.<p>
-//     * In the new line object, the indexes will range from 0 to <code>limit-start-1</code>.<p>
-//     *
-//     * This is used after calling <code>setPara()</code>
-//     * for a piece of text, and after line-breaking on that text.
-//     * It is not necessary if each paragraph is treated as a single line.<p>
-//     *
-//     * After line-breaking, rules (L1) and (L2) for the treatment of
-//     * trailing WS and for reordering are performed on
-//     * a <code>Bidi</code> object that represents a line.<p>
-//     *
-//     * <strong>Important: </strong>the line <code>Bidi</code> object may
-//     * reference data within the global text <code>Bidi</code> object.
-//     * You should not alter the content of the global text object until
-//     * you are finished using the line object.
-//     *
-//     * @param start is the line's first index into the text.
-//     *
-//     * @param limit is just behind the line's last index into the text
-//     *        (its last index +1).
-//     *
-//     * @return a <code>Bidi</code> object that will now represent a line of the text.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code>
-//     * @throws IllegalArgumentException if start and limit are not in the range
-//     *         <code>0&lt;=start&lt;limit&lt;=getProcessedLength()</code>,
-//     *         or if the specified line crosses a paragraph boundary
-//     *
-//     * @see #setPara
-//     * @see #getProcessedLength
-//     * @stable ICU 3.8
-//     */
-//    public Bidi setLine(int start, int limit)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Get the level for one character.
-     *
-     * @param charIndex the index of a character.
-     *
-     * @return The level for the character at <code>charIndex</code>.
-     *
-     * @throws IllegalStateException if this call is not preceded by a successful
-     *         call to <code>setPara</code> or <code>setLine</code>
-     * @throws IllegalArgumentException if charIndex is not in the range
-     *         <code>0&lt;=charIndex&lt;getProcessedLength()</code>
-     *
-     * @see #getProcessedLength
-     * @stable ICU 3.8
-     */
-    public byte getLevelAt(int charIndex)
-    {
-        return (byte)bidi.getLevelAt(charIndex);
-    }
-
-//    /**
-//     * Get an array of levels for each character.<p>
-//     *
-//     * Note that this method may allocate memory under some
-//     * circumstances, unlike <code>getLevelAt()</code>.
-//     *
-//     * @return The levels array for the text,
-//     *         or <code>null</code> if an error occurs.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     * @stable ICU 3.8
-//     */
-//    public byte[] getLevels()
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Get a logical run.
-//     * This method returns information about a run and is used
-//     * to retrieve runs in logical order.<p>
-//     * This is especially useful for line-breaking on a paragraph.
-//     *
-//     * @param logicalPosition is a logical position within the source text.
-//     *
-//     * @return a BidiRun object filled with <code>start</code> containing
-//     *        the first character of the run, <code>limit</code> containing
-//     *        the limit of the run, and <code>embeddingLevel</code> containing
-//     *        the level of the run.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     * @throws IllegalArgumentException if logicalPosition is not in the range
-//     *         <code>0&lt;=logicalPosition&lt;getProcessedLength()</code>
-//     *
-//     * @see com.ibm.icu.text.BidiRun
-//     * @see com.ibm.icu.text.BidiRun#getStart()
-//     * @see com.ibm.icu.text.BidiRun#getLimit()
-//     * @see com.ibm.icu.text.BidiRun#getEmbeddingLevel()
-//     *
-//     * @stable ICU 3.8
-//     */
-//    public BidiRun getLogicalRun(int logicalPosition)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Get the number of runs.
-//     * This method may invoke the actual reordering on the
-//     * <code>Bidi</code> object, after <code>setPara()</code>
-//     * may have resolved only the levels of the text. Therefore,
-//     * <code>countRuns()</code> may have to allocate memory,
-//     * and may throw an exception if it fails to do so.
-//     *
-//     * @return The number of runs.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     * @stable ICU 3.8
-//     */
-//    public int countRuns()
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     *
-//     * Get a <code>BidiRun</code> object according to its index. BidiRun methods
-//     * may be used to retrieve the run's logical start, length and level,
-//     * which can be even for an LTR run or odd for an RTL run.
-//     * In an RTL run, the character at the logical start is
-//     * visually on the right of the displayed run.
-//     * The length is the number of characters in the run.<p>
-//     * <code>countRuns()</code> is normally called
-//     * before the runs are retrieved.
-//     *
-//     * <p>
-//     *  Example:
-//     * <pre>
-//     *  Bidi bidi = new Bidi();
-//     *  String text = "abc 123 DEFG xyz";
-//     *  bidi.setPara(text, Bidi.RTL, null);
-//     *  int i, count=bidi.countRuns(), logicalStart, visualIndex=0, length;
-//     *  BidiRun run;
-//     *  for (i = 0; i &lt; count; ++i) {
-//     *      run = bidi.getVisualRun(i);
-//     *      logicalStart = run.getStart();
-//     *      length = run.getLength();
-//     *      if (Bidi.LTR == run.getEmbeddingLevel()) {
-//     *          do { // LTR
-//     *              show_char(text.charAt(logicalStart++), visualIndex++);
-//     *          } while (--length &gt; 0);
-//     *      } else {
-//     *          logicalStart += length;  // logicalLimit
-//     *          do { // RTL
-//     *              show_char(text.charAt(--logicalStart), visualIndex++);
-//     *          } while (--length &gt; 0);
-//     *      }
-//     *  }
-//     * </pre>
-//     * <p>
-//     * Note that in right-to-left runs, code like this places
-//     * second surrogates before first ones (which is generally a bad idea)
-//     * and combining characters before base characters.
-//     * <p>
-//     * Use of <code>{@link #writeReordered}</code>, optionally with the
-//     * <code>{@link #KEEP_BASE_COMBINING}</code> option, can be considered in
-//     * order to avoid these issues.
-//     *
-//     * @param runIndex is the number of the run in visual order, in the
-//     *        range <code>[0..countRuns()-1]</code>.
-//     *
-//     * @return a BidiRun object containing the details of the run. The
-//     *         directionality of the run is
-//     *         <code>LTR==0</code> or <code>RTL==1</code>,
-//     *         never <code>MIXED</code>.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     * @throws IllegalArgumentException if <code>runIndex</code> is not in
-//     *         the range <code>0&lt;=runIndex&lt;countRuns()</code>
-//     *
-//     * @see #countRuns()
-//     * @see com.ibm.icu.text.BidiRun
-//     * @see com.ibm.icu.text.BidiRun#getStart()
-//     * @see com.ibm.icu.text.BidiRun#getLength()
-//     * @see com.ibm.icu.text.BidiRun#getEmbeddingLevel()
-//     * @stable ICU 3.8
-//     */
-//    public BidiRun getVisualRun(int runIndex)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Get the visual position from a logical text position.
-//     * If such a mapping is used many times on the same
-//     * <code>Bidi</code> object, then calling
-//     * <code>getLogicalMap()</code> is more efficient.
-//     * <p>
-//     * The value returned may be <code>MAP_NOWHERE</code> if there is no
-//     * visual position because the corresponding text character is a Bidi
-//     * control removed from output by the option
-//     * <code>OPTION_REMOVE_CONTROLS</code>.
-//     * <p>
-//     * When the visual output is altered by using options of
-//     * <code>writeReordered()</code> such as <code>INSERT_LRM_FOR_NUMERIC</code>,
-//     * <code>KEEP_BASE_COMBINING</code>, <code>OUTPUT_REVERSE</code>,
-//     * <code>REMOVE_BIDI_CONTROLS</code>, the visual position returned may not
-//     * be correct. It is advised to use, when possible, reordering options
-//     * such as {@link #OPTION_INSERT_MARKS} and {@link #OPTION_REMOVE_CONTROLS}.
-//     * <p>
-//     * Note that in right-to-left runs, this mapping places
-//     * second surrogates before first ones (which is generally a bad idea)
-//     * and combining characters before base characters.
-//     * Use of <code>{@link #writeReordered}</code>, optionally with the
-//     * <code>{@link #KEEP_BASE_COMBINING}</code> option can be considered instead
-//     * of using the mapping, in order to avoid these issues.
-//     *
-//     * @param logicalIndex is the index of a character in the text.
-//     *
-//     * @return The visual position of this character.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     * @throws IllegalArgumentException if <code>logicalIndex</code> is not in
-//     *         the range <code>0&lt;=logicalIndex&lt;getProcessedLength()</code>
-//     *
-//     * @see #getLogicalMap
-//     * @see #getLogicalIndex
-//     * @see #getProcessedLength
-//     * @see #MAP_NOWHERE
-//     * @see #OPTION_REMOVE_CONTROLS
-//     * @see #writeReordered
-//     * @stable ICU 3.8
-//     */
-//    public int getVisualIndex(int logicalIndex)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-
-//    /**
-//     * Get the logical text position from a visual position.
-//     * If such a mapping is used many times on the same
-//     * <code>Bidi</code> object, then calling
-//     * <code>getVisualMap()</code> is more efficient.
-//     * <p>
-//     * The value returned may be <code>MAP_NOWHERE</code> if there is no
-//     * logical position because the corresponding text character is a Bidi
-//     * mark inserted in the output by option
-//     * <code>OPTION_INSERT_MARKS</code>.
-//     * <p>
-//     * This is the inverse method to <code>getVisualIndex()</code>.
-//     * <p>
-//     * When the visual output is altered by using options of
-//     * <code>writeReordered()</code> such as <code>INSERT_LRM_FOR_NUMERIC</code>,
-//     * <code>KEEP_BASE_COMBINING</code>, <code>OUTPUT_REVERSE</code>,
-//     * <code>REMOVE_BIDI_CONTROLS</code>, the logical position returned may not
-//     * be correct. It is advised to use, when possible, reordering options
-//     * such as {@link #OPTION_INSERT_MARKS} and {@link #OPTION_REMOVE_CONTROLS}.
-//     *
-//     * @param visualIndex is the visual position of a character.
-//     *
-//     * @return The index of this character in the text.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     * @throws IllegalArgumentException if <code>visualIndex</code> is not in
-//     *         the range <code>0&lt;=visualIndex&lt;getResultLength()</code>
-//     *
-//     * @see #getVisualMap
-//     * @see #getVisualIndex
-//     * @see #getResultLength
-//     * @see #MAP_NOWHERE
-//     * @see #OPTION_INSERT_MARKS
-//     * @see #writeReordered
-//     * @stable ICU 3.8
-//     */
-//    public int getLogicalIndex(int visualIndex)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Get a logical-to-visual index map (array) for the characters in the
-//     * <code>Bidi</code> (paragraph or line) object.
-//     * <p>
-//     * Some values in the map may be <code>MAP_NOWHERE</code> if the
-//     * corresponding text characters are Bidi controls removed from the visual
-//     * output by the option <code>OPTION_REMOVE_CONTROLS</code>.
-//     * <p>
-//     * When the visual output is altered by using options of
-//     * <code>writeReordered()</code> such as <code>INSERT_LRM_FOR_NUMERIC</code>,
-//     * <code>KEEP_BASE_COMBINING</code>, <code>OUTPUT_REVERSE</code>,
-//     * <code>REMOVE_BIDI_CONTROLS</code>, the visual positions returned may not
-//     * be correct. It is advised to use, when possible, reordering options
-//     * such as {@link #OPTION_INSERT_MARKS} and {@link #OPTION_REMOVE_CONTROLS}.
-//     * <p>
-//     * Note that in right-to-left runs, this mapping places
-//     * second surrogates before first ones (which is generally a bad idea)
-//     * and combining characters before base characters.
-//     * Use of <code>{@link #writeReordered}</code>, optionally with the
-//     * <code>{@link #KEEP_BASE_COMBINING}</code> option can be considered instead
-//     * of using the mapping, in order to avoid these issues.
-//     *
-//     * @return an array of <code>getProcessedLength()</code>
-//     *        indexes which will reflect the reordering of the characters.<br><br>
-//     *        The index map will result in
-//     *        <code>indexMap[logicalIndex]==visualIndex</code>, where
-//     *        <code>indexMap</code> represents the returned array.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     *
-//     * @see #getVisualMap
-//     * @see #getVisualIndex
-//     * @see #getProcessedLength
-//     * @see #MAP_NOWHERE
-//     * @see #OPTION_REMOVE_CONTROLS
-//     * @see #writeReordered
-//     * @stable ICU 3.8
-//     */
-//    public int[] getLogicalMap()
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Get a visual-to-logical index map (array) for the characters in the
-//     * <code>Bidi</code> (paragraph or line) object.
-//     * <p>
-//     * Some values in the map may be <code>MAP_NOWHERE</code> if the
-//     * corresponding text characters are Bidi marks inserted in the visual
-//     * output by the option <code>OPTION_INSERT_MARKS</code>.
-//     * <p>
-//     * When the visual output is altered by using options of
-//     * <code>writeReordered()</code> such as <code>INSERT_LRM_FOR_NUMERIC</code>,
-//     * <code>KEEP_BASE_COMBINING</code>, <code>OUTPUT_REVERSE</code>,
-//     * <code>REMOVE_BIDI_CONTROLS</code>, the logical positions returned may not
-//     * be correct. It is advised to use, when possible, reordering options
-//     * such as {@link #OPTION_INSERT_MARKS} and {@link #OPTION_REMOVE_CONTROLS}.
-//     *
-//     * @return an array of <code>getResultLength()</code>
-//     *        indexes which will reflect the reordering of the characters.<br><br>
-//     *        The index map will result in
-//     *        <code>indexMap[visualIndex]==logicalIndex</code>, where
-//     *        <code>indexMap</code> represents the returned array.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     *
-//     * @see #getLogicalMap
-//     * @see #getLogicalIndex
-//     * @see #getResultLength
-//     * @see #MAP_NOWHERE
-//     * @see #OPTION_INSERT_MARKS
-//     * @see #writeReordered
-//     * @stable ICU 3.8
-//     */
-//    public int[] getVisualMap()
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * This is a convenience method that does not use a <code>Bidi</code> object.
-//     * It is intended to be used for when an application has determined the levels
-//     * of objects (character sequences) and just needs to have them reordered (L2).
-//     * This is equivalent to using <code>getLogicalMap()</code> on a
-//     * <code>Bidi</code> object.
-//     *
-//     * @param levels is an array of levels that have been determined by
-//     *        the application.
-//     *
-//     * @return an array of <code>levels.length</code>
-//     *        indexes which will reflect the reordering of the characters.<p>
-//     *        The index map will result in
-//     *        <code>indexMap[logicalIndex]==visualIndex</code>, where
-//     *        <code>indexMap</code> represents the returned array.
-//     *
-//     * @stable ICU 3.8
-//     */
-//    public static int[] reorderLogical(byte[] levels)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * This is a convenience method that does not use a <code>Bidi</code> object.
-//     * It is intended to be used for when an application has determined the levels
-//     * of objects (character sequences) and just needs to have them reordered (L2).
-//     * This is equivalent to using <code>getVisualMap()</code> on a
-//     * <code>Bidi</code> object.
-//     *
-//     * @param levels is an array of levels that have been determined by
-//     *        the application.
-//     *
-//     * @return an array of <code>levels.length</code>
-//     *        indexes which will reflect the reordering of the characters.<p>
-//     *        The index map will result in
-//     *        <code>indexMap[visualIndex]==logicalIndex</code>, where
-//     *        <code>indexMap</code> represents the returned array.
-//     *
-//     * @stable ICU 3.8
-//     */
-//    public static int[] reorderVisual(byte[] levels)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Invert an index map.
-//     * The index mapping of the argument map is inverted and returned as
-//     * an array of indexes that we will call the inverse map.
-//     *
-//     * @param srcMap is an array whose elements define the original mapping
-//     * from a source array to a destination array.
-//     * Some elements of the source array may have no mapping in the
-//     * destination array. In that case, their value will be
-//     * the special value <code>MAP_NOWHERE</code>.
-//     * All elements must be >=0 or equal to <code>MAP_NOWHERE</code>.
-//     * Some elements in the source map may have a value greater than the
-//     * srcMap.length if the destination array has more elements than the
-//     * source array.
-//     * There must be no duplicate indexes (two or more elements with the
-//     * same value except <code>MAP_NOWHERE</code>).
-//     *
-//     * @return an array representing the inverse map.
-//     *         This array has a number of elements equal to 1 + the highest
-//     *         value in <code>srcMap</code>.
-//     *         For elements of the result array which have no matching elements
-//     *         in the source array, the corresponding elements in the inverse
-//     *         map will receive a value equal to <code>MAP_NOWHERE</code>.
-//     *         If element with index i in <code>srcMap</code> has a value k different
-//     *         from <code>MAP_NOWHERE</code>, this means that element i of
-//     *         the source array maps to element k in the destination array.
-//     *         The inverse map will have value i in its k-th element.
-//     *         For all elements of the destination array which do not map to
-//     *         an element in the source array, the corresponding element in the
-//     *         inverse map will have a value equal to <code>MAP_NOWHERE</code>.
-//     *
-//     * @see #MAP_NOWHERE
-//     * @stable ICU 3.8
-//     */
-//    public static int[] invertMap(int[] srcMap)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /*
-     * Fields and methods for compatibility with java.text.bidi (Sun implementation)
-     */
-
-    /**
-     * Constant indicating base direction is left-to-right.
-     * @stable ICU 3.8
-     */
-    public static final int DIRECTION_LEFT_TO_RIGHT = LTR;
-
-    /**
-     * Constant indicating base direction is right-to-left.
-     * @stable ICU 3.8
-     */
-    public static final int DIRECTION_RIGHT_TO_LEFT = RTL;
-
-    /**
-     * Constant indicating that the base direction depends on the first strong
-     * directional character in the text according to the Unicode Bidirectional
-     * Algorithm. If no strong directional character is present, the base
-     * direction is left-to-right.
-     * @stable ICU 3.8
-     */
-    public static final int DIRECTION_DEFAULT_LEFT_TO_RIGHT = LEVEL_DEFAULT_LTR;
-
-    /**
-     * Constant indicating that the base direction depends on the first strong
-     * directional character in the text according to the Unicode Bidirectional
-     * Algorithm. If no strong directional character is present, the base
-     * direction is right-to-left.
-     * @stable ICU 3.8
-     */
-    public static final int DIRECTION_DEFAULT_RIGHT_TO_LEFT = LEVEL_DEFAULT_RTL;
-
-    /**
-     * Create Bidi from the given paragraph of text and base direction.
-     *
-     * @param paragraph a paragraph of text
-     * @param flags a collection of flags that control the algorithm. The
-     *        algorithm understands the flags DIRECTION_LEFT_TO_RIGHT,
-     *        DIRECTION_RIGHT_TO_LEFT, DIRECTION_DEFAULT_LEFT_TO_RIGHT, and
-     *        DIRECTION_DEFAULT_RIGHT_TO_LEFT. Other values are reserved.
-     * @see #DIRECTION_LEFT_TO_RIGHT
-     * @see #DIRECTION_RIGHT_TO_LEFT
-     * @see #DIRECTION_DEFAULT_LEFT_TO_RIGHT
-     * @see #DIRECTION_DEFAULT_RIGHT_TO_LEFT
-     * @stable ICU 3.8
-     */
-    public Bidi(String paragraph, int flags)
-    {
-        // Note: ICU and Oracle JDK are using the
-        // same DIRECTION_* flags definitions.
-        this(new java.text.Bidi(paragraph, flags));
-    }
-
-    /**
-     * Create Bidi from the given paragraph of text.<p>
-     *
-     * The RUN_DIRECTION attribute in the text, if present, determines the base
-     * direction (left-to-right or right-to-left). If not present, the base
-     * direction is computed using the Unicode Bidirectional Algorithm,
-     * defaulting to left-to-right if there are no strong directional characters
-     * in the text. This attribute, if present, must be applied to all the text
-     * in the paragraph.<p>
-     *
-     * The BIDI_EMBEDDING attribute in the text, if present, represents
-     * embedding level information. Negative values from -1 to -62 indicate
-     * overrides at the absolute value of the level. Positive values from 1 to
-     * 62 indicate embeddings. Where values are zero or not defined, the base
-     * embedding level as determined by the base direction is assumed.<p>
-     *
-     * The NUMERIC_SHAPING attribute in the text, if present, converts European
-     * digits to other decimal digits before running the bidi algorithm. This
-     * attribute, if present, must be applied to all the text in the paragraph.<p>
-     *
-     * Note: this constructor calls setPara() internally.
-     *
-     * @param paragraph a paragraph of text with optional character and
-     *        paragraph attribute information
-     * @stable ICU 3.8
-     */
-    public Bidi(AttributedCharacterIterator paragraph)
-    {
-        // ICU does not define its own attributes and just
-        // use java.awt.font.TextAttribute. Thus, no mappings
-        // are necessary.
-        this(new java.text.Bidi(paragraph));
-    }
-
-    /**
-     * Create Bidi from the given text, embedding, and direction information.
-     * The embeddings array may be null. If present, the values represent
-     * embedding level information. Negative values from -1 to -61 indicate
-     * overrides at the absolute value of the level. Positive values from 1 to
-     * 61 indicate embeddings. Where values are zero, the base embedding level
-     * as determined by the base direction is assumed.<p>
-     *
-     * Note: this constructor calls setPara() internally.
-     *
-     * @param text an array containing the paragraph of text to process.
-     * @param textStart the index into the text array of the start of the
-     *        paragraph.
-     * @param embeddings an array containing embedding values for each character
-     *        in the paragraph. This can be null, in which case it is assumed
-     *        that there is no external embedding information.
-     * @param embStart the index into the embedding array of the start of the
-     *        paragraph.
-     * @param paragraphLength the length of the paragraph in the text and
-     *        embeddings arrays.
-     * @param flags a collection of flags that control the algorithm. The
-     *        algorithm understands the flags DIRECTION_LEFT_TO_RIGHT,
-     *        DIRECTION_RIGHT_TO_LEFT, DIRECTION_DEFAULT_LEFT_TO_RIGHT, and
-     *        DIRECTION_DEFAULT_RIGHT_TO_LEFT. Other values are reserved.
-     *
-     * @throws IllegalArgumentException if the values in embeddings are
-     *         not within the allowed range
-     *
-     * @see #DIRECTION_LEFT_TO_RIGHT
-     * @see #DIRECTION_RIGHT_TO_LEFT
-     * @see #DIRECTION_DEFAULT_LEFT_TO_RIGHT
-     * @see #DIRECTION_DEFAULT_RIGHT_TO_LEFT
-     * @stable ICU 3.8
-     */
-    public Bidi(char[] text,
-            int textStart,
-            byte[] embeddings,
-            int embStart,
-            int paragraphLength,
-            int flags)
-    {
-        // Note: ICU and Oracle JDK are using the
-        // same DIRECTION_* flags definitions.
-        this(new java.text.Bidi(text, textStart, embeddings, embStart, paragraphLength, flags));
-    }
-
-    /**
-     * Create a Bidi object representing the bidi information on a line of text
-     * within the paragraph represented by the current Bidi. This call is not
-     * required if the entire paragraph fits on one line.
-     *
-     * @param lineStart the offset from the start of the paragraph to the start
-     *        of the line.
-     * @param lineLimit the offset from the start of the paragraph to the limit
-     *        of the line.
-     *
-     * @throws IllegalStateException if this call is not preceded by a successful
-     *         call to <code>setPara</code>
-     * @throws IllegalArgumentException if lineStart and lineLimit are not in the range
-     *         <code>0&lt;=lineStart&lt;lineLimit&lt;=getProcessedLength()</code>,
-     *         or if the specified line crosses a paragraph boundary
-     * @stable ICU 3.8
-     */
-    public Bidi createLineBidi(int lineStart, int lineLimit)
-    {
-        return new Bidi(bidi.createLineBidi(lineStart, lineLimit));
-    }
-
-    /**
-     * Return true if the line is not left-to-right or right-to-left. This means
-     * it either has mixed runs of left-to-right and right-to-left text, or the
-     * base direction differs from the direction of the only run of text.
-     *
-     * @return true if the line is not left-to-right or right-to-left.
-     *
-     * @throws IllegalStateException if this call is not preceded by a successful
-     *         call to <code>setPara</code>
-     * @stable ICU 3.8
-     */
-    public boolean isMixed()
-    {
-        return bidi.isMixed();
-    }
-
-    /**
-     * Return true if the line is all left-to-right text and the base direction
-     * is left-to-right.
-     *
-     * @return true if the line is all left-to-right text and the base direction
-     *         is left-to-right.
-     *
-     * @throws IllegalStateException if this call is not preceded by a successful
-     *         call to <code>setPara</code>
-     * @stable ICU 3.8
-     */
-    public boolean isLeftToRight()
-    {
-        return bidi.isLeftToRight();
-    }
-
-    /**
-     * Return true if the line is all right-to-left text, and the base direction
-     * is right-to-left
-     *
-     * @return true if the line is all right-to-left text, and the base
-     *         direction is right-to-left
-     *
-     * @throws IllegalStateException if this call is not preceded by a successful
-     *         call to <code>setPara</code>
-     * @stable ICU 3.8
-     */
-    public boolean isRightToLeft()
-    {
-        return bidi.isRightToLeft();
-    }
-
-    /**
-     * Return true if the base direction is left-to-right
-     *
-     * @return true if the base direction is left-to-right
-     *
-     * @throws IllegalStateException if this call is not preceded by a successful
-     *         call to <code>setPara</code> or <code>setLine</code>
-     *
-     * @stable ICU 3.8
-     */
-    public boolean baseIsLeftToRight()
-    {
-        return bidi.baseIsLeftToRight();
-    }
-
-    /**
-     * Return the base level (0 if left-to-right, 1 if right-to-left).
-     *
-     * @return the base level
-     *
-     * @throws IllegalStateException if this call is not preceded by a successful
-     *         call to <code>setPara</code> or <code>setLine</code>
-     *
-     * @stable ICU 3.8
-     */
-    public int getBaseLevel()
-    {
-        return bidi.getBaseLevel();
-    }
-
-    /**
-     * Return the number of level runs.
-     *
-     * @return the number of level runs
-     *
-     * @throws IllegalStateException if this call is not preceded by a successful
-     *         call to <code>setPara</code> or <code>setLine</code>
-     *
-     * @stable ICU 3.8
-     */
-    public int getRunCount()
-    {
-        return bidi.getRunCount();
-    }
-
-    /**
-     * Return the level of the nth logical run in this line.
-     *
-     * @param run the index of the run, between 0 and <code>countRuns()-1</code>
-     *
-     * @return the level of the run
-     *
-     * @throws IllegalStateException if this call is not preceded by a successful
-     *         call to <code>setPara</code> or <code>setLine</code>
-     * @throws IllegalArgumentException if <code>run</code> is not in
-     *         the range <code>0&lt;=run&lt;countRuns()</code>
-     * @stable ICU 3.8
-     */
-    public int getRunLevel(int run)
-    {
-        return bidi.getRunLevel(run);
-    }
-
-    /**
-     * Return the index of the character at the start of the nth logical run in
-     * this line, as an offset from the start of the line.
-     *
-     * @param run the index of the run, between 0 and <code>countRuns()</code>
-     *
-     * @return the start of the run
-     *
-     * @throws IllegalStateException if this call is not preceded by a successful
-     *         call to <code>setPara</code> or <code>setLine</code>
-     * @throws IllegalArgumentException if <code>run</code> is not in
-     *         the range <code>0&lt;=run&lt;countRuns()</code>
-     * @stable ICU 3.8
-     */
-    public int getRunStart(int run)
-    {
-        return bidi.getRunStart(run);
-    }
-
-    /**
-     * Return the index of the character past the end of the nth logical run in
-     * this line, as an offset from the start of the line. For example, this
-     * will return the length of the line for the last run on the line.
-     *
-     * @param run the index of the run, between 0 and <code>countRuns()</code>
-     *
-     * @return the limit of the run
-     *
-     * @throws IllegalStateException if this call is not preceded by a successful
-     *         call to <code>setPara</code> or <code>setLine</code>
-     * @throws IllegalArgumentException if <code>run</code> is not in
-     *         the range <code>0&lt;=run&lt;countRuns()</code>
-     * @stable ICU 3.8
-     */
-    public int getRunLimit(int run)
-    {
-        return bidi.getRunLimit(run);
-    }
-
-    /**
-     * Return true if the specified text requires bidi analysis. If this returns
-     * false, the text will display left-to-right. Clients can then avoid
-     * constructing a Bidi object. Text in the Arabic Presentation Forms area of
-     * Unicode is presumed to already be shaped and ordered for display, and so
-     * will not cause this method to return true.
-     *
-     * @param text the text containing the characters to test
-     * @param start the start of the range of characters to test
-     * @param limit the limit of the range of characters to test
-     *
-     * @return true if the range of characters requires bidi analysis
-     *
-     * @stable ICU 3.8
-     */
-    public static boolean requiresBidi(char[] text,
-            int start,
-            int limit)
-    {
-        return java.text.Bidi.requiresBidi(text, start, limit);
-    }
-
-    /**
-     * Reorder the objects in the array into visual order based on their levels.
-     * This is a utility method to use when you have a collection of objects
-     * representing runs of text in logical order, each run containing text at a
-     * single level. The elements at <code>index</code> from
-     * <code>objectStart</code> up to <code>objectStart + count</code> in the
-     * objects array will be reordered into visual order assuming
-     * each run of text has the level indicated by the corresponding element in
-     * the levels array (at <code>index - objectStart + levelStart</code>).
-     *
-     * @param levels an array representing the bidi level of each object
-     * @param levelStart the start position in the levels array
-     * @param objects the array of objects to be reordered into visual order
-     * @param objectStart the start position in the objects array
-     * @param count the number of objects to reorder
-     * @stable ICU 3.8
-     */
-    public static void reorderVisually(byte[] levels,
-            int levelStart,
-            Object[] objects,
-            int objectStart,
-            int count)
-    {
-        java.text.Bidi.reorderVisually(levels, levelStart, objects, objectStart, count);
-    }
-
-//    /**
-//     * Take a <code>Bidi</code> object containing the reordering
-//     * information for a piece of text (one or more paragraphs) set by
-//     * <code>setPara()</code> or for a line of text set by <code>setLine()</code>
-//     * and return a string containing the reordered text.
-//     *
-//     * <p>The text may have been aliased (only a reference was stored
-//     * without copying the contents), thus it must not have been modified
-//     * since the <code>setPara()</code> call.</p>
-//     *
-//     * This method preserves the integrity of characters with multiple
-//     * code units and (optionally) combining characters.
-//     * Characters in RTL runs can be replaced by mirror-image characters
-//     * in the returned string. Note that "real" mirroring has to be done in a
-//     * rendering engine by glyph selection and that for many "mirrored"
-//     * characters there are no Unicode characters as mirror-image equivalents.
-//     * There are also options to insert or remove Bidi control
-//     * characters; see the descriptions of the return value and the
-//     * <code>options</code> parameter, and of the option bit flags.
-//     *
-//     * @param options A bit set of options for the reordering that control
-//     *                how the reordered text is written.
-//     *                The options include mirroring the characters on a code
-//     *                point basis and inserting LRM characters, which is used
-//     *                especially for transforming visually stored text
-//     *                to logically stored text (although this is still an
-//     *                imperfect implementation of an "inverse Bidi" algorithm
-//     *                because it uses the "forward Bidi" algorithm at its core).
-//     *                The available options are:
-//     *                <code>DO_MIRRORING</code>,
-//     *                <code>INSERT_LRM_FOR_NUMERIC</code>,
-//     *                <code>KEEP_BASE_COMBINING</code>,
-//     *                <code>OUTPUT_REVERSE</code>,
-//     *                <code>REMOVE_BIDI_CONTROLS</code>,
-//     *                <code>STREAMING</code>
-//     *
-//     * @return The reordered text.
-//     *         If the <code>INSERT_LRM_FOR_NUMERIC</code> option is set, then
-//     *         the length of the returned string could be as large as
-//     *         <code>getLength()+2*countRuns()</code>.<br>
-//     *         If the <code>REMOVE_BIDI_CONTROLS</code> option is set, then the
-//     *         length of the returned string may be less than
-//     *         <code>getLength()</code>.<br>
-//     *         If none of these options is set, then the length of the returned
-//     *         string will be exactly <code>getProcessedLength()</code>.
-//     *
-//     * @throws IllegalStateException if this call is not preceded by a successful
-//     *         call to <code>setPara</code> or <code>setLine</code>
-//     *
-//     * @see #DO_MIRRORING
-//     * @see #INSERT_LRM_FOR_NUMERIC
-//     * @see #KEEP_BASE_COMBINING
-//     * @see #OUTPUT_REVERSE
-//     * @see #REMOVE_BIDI_CONTROLS
-//     * @see #OPTION_STREAMING
-//     * @see #getProcessedLength
-//     * @stable ICU 3.8
-//     */
-//    public String writeReordered(int options)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Reverse a Right-To-Left run of Unicode text.
-//     *
-//     * This method preserves the integrity of characters with multiple
-//     * code units and (optionally) combining characters.
-//     * Characters can be replaced by mirror-image characters
-//     * in the destination buffer. Note that "real" mirroring has
-//     * to be done in a rendering engine by glyph selection
-//     * and that for many "mirrored" characters there are no
-//     * Unicode characters as mirror-image equivalents.
-//     * There are also options to insert or remove Bidi control
-//     * characters.
-//     *
-//     * This method is the implementation for reversing RTL runs as part
-//     * of <code>writeReordered()</code>. For detailed descriptions
-//     * of the parameters, see there.
-//     * Since no Bidi controls are inserted here, the output string length
-//     * will never exceed <code>src.length()</code>.
-//     *
-//     * @see #writeReordered
-//     *
-//     * @param src The RTL run text.
-//     *
-//     * @param options A bit set of options for the reordering that control
-//     *                how the reordered text is written.
-//     *                See the <code>options</code> parameter in <code>writeReordered()</code>.
-//     *
-//     * @return The reordered text.
-//     *         If the <code>REMOVE_BIDI_CONTROLS</code> option
-//     *         is set, then the length of the returned string may be less than
-//     *         <code>src.length()</code>. If this option is not set,
-//     *         then the length of the returned string will be exactly
-//     *         <code>src.length()</code>.
-//     *
-//     * @throws IllegalArgumentException if <code>src</code> is null.
-//     * @stable ICU 3.8
-//     */
-//    public static String writeReverse(String src, int options)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Get the base direction of the text provided according to the Unicode
-//     * Bidirectional Algorithm. The base direction is derived from the first
-//     * character in the string with bidirectional character type L, R, or AL.
-//     * If the first such character has type L, LTR is returned. If the first
-//     * such character has type R or AL, RTL is returned. If the string does
-//     * not contain any character of these types, then NEUTRAL is returned.
-//     * This is a lightweight function for use when only the base direction is
-//     * needed and no further bidi processing of the text is needed.
-//     * @param paragraph the text whose paragraph level direction is needed.
-//     * @return LTR, RTL, NEUTRAL
-//     * @see #LTR
-//     * @see #RTL
-//     * @see #NEUTRAL
-//     * @draft ICU 4.6
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public static byte getBaseDirection(CharSequence paragraph) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Set the context before a call to setPara().<p>
-//     *
-//     * setPara() computes the left-right directionality for a given piece
-//     * of text which is supplied as one of its arguments. Sometimes this piece
-//     * of text (the "main text") should be considered in context, because text
-//     * appearing before ("prologue") and/or after ("epilogue") the main text
-//     * may affect the result of this computation.<p>
-//     *
-//     * This function specifies the prologue and/or the epilogue for the next
-//     * call to setPara(). If successive calls to setPara()
-//     * all need specification of a context, setContext() must be called
-//     * before each call to setPara(). In other words, a context is not
-//     * "remembered" after the following successful call to setPara().<p>
-//     *
-//     * If a call to setPara() specifies DEFAULT_LTR or
-//     * DEFAULT_RTL as paraLevel and is preceded by a call to
-//     * setContext() which specifies a prologue, the paragraph level will
-//     * be computed taking in consideration the text in the prologue.<p>
-//     *
-//     * When setPara() is called without a previous call to
-//     * setContext, the main text is handled as if preceded and followed
-//     * by strong directional characters at the current paragraph level.
-//     * Calling setContext() with specification of a prologue will change
-//     * this behavior by handling the main text as if preceded by the last
-//     * strong character appearing in the prologue, if any.
-//     * Calling setContext() with specification of an epilogue will change
-//     * the behavior of setPara() by handling the main text as if followed
-//     * by the first strong character or digit appearing in the epilogue, if any.<p>
-//     *
-//     * Note 1: if <code>setContext</code> is called repeatedly without
-//     *         calling <code>setPara</code>, the earlier calls have no effect,
-//     *         only the last call will be remembered for the next call to
-//     *         <code>setPara</code>.<p>
-//     *
-//     * Note 2: calling <code>setContext(null, null)</code>
-//     *         cancels any previous setting of non-empty prologue or epilogue.
-//     *         The next call to <code>setPara()</code> will process no
-//     *         prologue or epilogue.<p>
-//     *
-//     * Note 3: users must be aware that even after setting the context
-//     *         before a call to setPara() to perform e.g. a logical to visual
-//     *         transformation, the resulting string may not be identical to what it
-//     *         would have been if all the text, including prologue and epilogue, had
-//     *         been processed together.<br>
-//     * Example (upper case letters represent RTL characters):<br>
-//     * &nbsp;&nbsp;prologue = "<code>abc DE</code>"<br>
-//     * &nbsp;&nbsp;epilogue = none<br>
-//     * &nbsp;&nbsp;main text = "<code>FGH xyz</code>"<br>
-//     * &nbsp;&nbsp;paraLevel = LTR<br>
-//     * &nbsp;&nbsp;display without prologue = "<code>HGF xyz</code>"
-//     *             ("HGF" is adjacent to "xyz")<br>
-//     * &nbsp;&nbsp;display with prologue = "<code>abc HGFED xyz</code>"
-//     *             ("HGF" is not adjacent to "xyz")<br>
-//     *
-//     * @param prologue is the text which precedes the text that
-//     *        will be specified in a coming call to setPara().
-//     *        If there is no prologue to consider,
-//     *        this parameter can be <code>null</code>.
-//     *
-//     * @param epilogue is the text which follows the text that
-//     *        will be specified in a coming call to setPara().
-//     *        If there is no epilogue to consider,
-//     *        this parameter can be <code>null</code>.
-//     *
-//     * @see #setPara
-//     * @draft ICU 4.8
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public void setContext(String prologue, String epilogue) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BreakIterator.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BreakIterator.java
deleted file mode 100644
index 9d61164..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/BreakIterator.java
+++ /dev/null
@@ -1,835 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 1996-2012, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.text;
-
-import java.text.CharacterIterator;
-import java.text.StringCharacterIterator;
-import java.util.Locale;
-
-import com.ibm.icu.util.ULocale;
-
-/**
- * {@icuenhanced java.text.BreakIterator}.{@icu _usage_}
- *
- * <p>A class that locates boundaries in text.  This class defines a protocol for
- * objects that break up a piece of natural-language text according to a set
- * of criteria.  Instances or subclasses of BreakIterator can be provided, for
- * example, to break a piece of text into words, sentences, or logical characters
- * according to the conventions of some language or group of languages.
- *
- * We provide five built-in types of BreakIterator:
- * <ul><li>getTitleInstance() returns a BreakIterator that locates boundaries
- * between title breaks.
- * <li>getSentenceInstance() returns a BreakIterator that locates boundaries
- * between sentences.  This is useful for triple-click selection, for example.
- * <li>getWordInstance() returns a BreakIterator that locates boundaries between
- * words.  This is useful for double-click selection or "find whole words" searches.
- * This type of BreakIterator makes sure there is a boundary position at the
- * beginning and end of each legal word.  (Numbers count as words, too.)  Whitespace
- * and punctuation are kept separate from real words.
- * <li>getLineInstance() returns a BreakIterator that locates positions where it is
- * legal for a text editor to wrap lines.  This is similar to word breaking, but
- * not the same: punctuation and whitespace are generally kept with words (you don't
- * want a line to start with whitespace, for example), and some special characters
- * can force a position to be considered a line-break position or prevent a position
- * from being a line-break position.
- * <li>getCharacterInstance() returns a BreakIterator that locates boundaries between
- * logical characters.  Because of the structure of the Unicode encoding, a logical
- * character may be stored internally as more than one Unicode code point.  (A with an
- * umlaut may be stored as an a followed by a separate combining umlaut character,
- * for example, but the user still thinks of it as one character.)  This iterator allows
- * various processes (especially text editors) to treat as characters the units of text
- * that a user would think of as characters, rather than the units of text that the
- * computer sees as "characters".</ul>
- *
- * BreakIterator's interface follows an "iterator" model (hence the name), meaning it
- * has a concept of a "current position" and methods like first(), last(), next(),
- * and previous() that update the current position.  All BreakIterators uphold the
- * following invariants:
- * <ul><li>The beginning and end of the text are always treated as boundary positions.
- * <li>The current position of the iterator is always a boundary position (random-
- * access methods move the iterator to the nearest boundary position before or
- * after the specified position, not _to_ the specified position).
- * <li>DONE is used as a flag to indicate when iteration has stopped.  DONE is only
- * returned when the current position is the end of the text and the user calls next(),
- * or when the current position is the beginning of the text and the user calls
- * previous().
- * <li>Break positions are numbered by the positions of the characters that follow
- * them.  Thus, under normal circumstances, the position before the first character
- * is 0, the position after the first character is 1, and the position after the
- * last character is 1 plus the length of the string.
- * <li>The client can change the position of an iterator, or the text it analyzes,
- * at will, but cannot change the behavior.  If the user wants different behavior, he
- * must instantiate a new iterator.</ul>
- *
- * BreakIterator accesses the text it analyzes through a CharacterIterator, which makes
- * it possible to use BreakIterator to analyze text in any text-storage vehicle that
- * provides a CharacterIterator interface.
- *
- * <b>Note:</b>  Some types of BreakIterator can take a long time to create, and
- * instances of BreakIterator are not currently cached by the system.  For
- * optimal performance, keep instances of BreakIterator around as long as makes
- * sense.  For example, when word-wrapping a document, don't create and destroy a
- * new BreakIterator for each line.  Create one break iterator for the whole document
- * (or whatever stretch of text you're wrapping) and use it to do the whole job of
- * wrapping the text.
- *
-  * <P>
- * <strong>Examples</strong>:<P>
- * Creating and using text boundaries
- * <blockquote>
- * <pre>
- * public static void main(String args[]) {
- *      if (args.length == 1) {
- *          String stringToExamine = args[0];
- *          //print each word in order
- *          BreakIterator boundary = BreakIterator.getWordInstance();
- *          boundary.setText(stringToExamine);
- *          printEachForward(boundary, stringToExamine);
- *          //print each sentence in reverse order
- *          boundary = BreakIterator.getSentenceInstance(Locale.US);
- *          boundary.setText(stringToExamine);
- *          printEachBackward(boundary, stringToExamine);
- *          printFirst(boundary, stringToExamine);
- *          printLast(boundary, stringToExamine);
- *      }
- * }
- * </pre>
- * </blockquote>
- *
- * Print each element in order
- * <blockquote>
- * <pre>
- * public static void printEachForward(BreakIterator boundary, String source) {
- *     int start = boundary.first();
- *     for (int end = boundary.next();
- *          end != BreakIterator.DONE;
- *          start = end, end = boundary.next()) {
- *          System.out.println(source.substring(start,end));
- *     }
- * }
- * </pre>
- * </blockquote>
- *
- * Print each element in reverse order
- * <blockquote>
- * <pre>
- * public static void printEachBackward(BreakIterator boundary, String source) {
- *     int end = boundary.last();
- *     for (int start = boundary.previous();
- *          start != BreakIterator.DONE;
- *          end = start, start = boundary.previous()) {
- *         System.out.println(source.substring(start,end));
- *     }
- * }
- * </pre>
- * </blockquote>
- *
- * Print first element
- * <blockquote>
- * <pre>
- * public static void printFirst(BreakIterator boundary, String source) {
- *     int start = boundary.first();
- *     int end = boundary.next();
- *     System.out.println(source.substring(start,end));
- * }
- * </pre>
- * </blockquote>
- *
- * Print last element
- * <blockquote>
- * <pre>
- * public static void printLast(BreakIterator boundary, String source) {
- *     int end = boundary.last();
- *     int start = boundary.previous();
- *     System.out.println(source.substring(start,end));
- * }
- * </pre>
- * </blockquote>
- *
- * Print the element at a specified position
- * <blockquote>
- * <pre>
- * public static void printAt(BreakIterator boundary, int pos, String source) {
- *     int end = boundary.following(pos);
- *     int start = boundary.previous();
- *     System.out.println(source.substring(start,end));
- * }
- * </pre>
- * </blockquote>
- *
- * Find the next word
- * <blockquote>
- * <pre>
- * public static int nextWordStartAfter(int pos, String text) {
- *     BreakIterator wb = BreakIterator.getWordInstance();
- *     wb.setText(text);
- *     int last = wb.following(pos);
- *     int current = wb.next();
- *     while (current != BreakIterator.DONE) {
- *         for (int p = last; p < current; p++) {
- *             if (Character.isLetter(text.charAt(p)))
- *                 return last;
- *         }
- *         last = current;
- *         current = wb.next();
- *     }
- *     return BreakIterator.DONE;
- * }
- * </pre>
- * (The iterator returned by BreakIterator.getWordInstance() is unique in that
- * the break positions it returns don't represent both the start and end of the
- * thing being iterated over.  That is, a sentence-break iterator returns breaks
- * that each represent the end of one sentence and the beginning of the next.
- * With the word-break iterator, the characters between two boundaries might be a
- * word, or they might be the punctuation or whitespace between two words.  The
- * above code uses a simple heuristic to determine which boundary is the beginning
- * of a word: If the characters between this boundary and the next boundary
- * include at least one letter (this can be an alphabetical letter, a CJK ideograph,
- * a Hangul syllable, a Kana character, etc.), then the text between this boundary
- * and the next is a word; otherwise, it's the material between words.)
- * </blockquote>
- *
- * @see CharacterIterator
- * @stable ICU 2.0
- *
- */
-
-public abstract class BreakIterator implements Cloneable
-{
-
-    /**
-     * Default constructor.  There is no state that is carried by this abstract
-     * base class.
-     * @stable ICU 2.0
-     */
-    protected BreakIterator()
-    {
-    }
-
-    /**
-     * Clone method.  Creates another BreakIterator with the same behavior and
-     * current state as this one.
-     * @return The clone.
-     * @stable ICU 2.0
-     */
-    public Object clone()
-    {
-        try {
-            return super.clone();
-        }
-        catch (CloneNotSupportedException e) {
-            ///CLOVER:OFF
-            throw new IllegalStateException();
-            ///CLOVER:ON
-        }
-    }
-
-    /**
-     * DONE is returned by previous() and next() after all valid
-     * boundaries have been returned.
-     * @stable ICU 2.0
-     */
-    public static final int DONE = -1;
-
-    /**
-     * Return the first boundary position.  This is always the beginning
-     * index of the text this iterator iterates over.  For example, if
-     * the iterator iterates over a whole string, this function will
-     * always return 0.  This function also updates the iteration position
-     * to point to the beginning of the text.
-     * @return The character offset of the beginning of the stretch of text
-     * being broken.
-     * @stable ICU 2.0
-     */
-    public abstract int first();
-
-    /**
-     * Return the last boundary position.  This is always the "past-the-end"
-     * index of the text this iterator iterates over.  For example, if the
-     * iterator iterates over a whole string (call it "text"), this function
-     * will always return text.length().  This function also updated the
-     * iteration position to point to the end of the text.
-     * @return The character offset of the end of the stretch of text
-     * being broken.
-     * @stable ICU 2.0
-     */
-    public abstract int last();
-
-    /**
-     * Advances the specified number of steps forward in the text (a negative
-     * number, therefore, advances backwards).  If this causes the iterator
-     * to advance off either end of the text, this function returns DONE;
-     * otherwise, this function returns the position of the appropriate
-     * boundary.  Calling this function is equivalent to calling next() or
-     * previous() n times.
-     * @param n The number of boundaries to advance over (if positive, moves
-     * forward; if negative, moves backwards).
-     * @return The position of the boundary n boundaries from the current
-     * iteration position, or DONE if moving n boundaries causes the iterator
-     * to advance off either end of the text.
-     * @stable ICU 2.0
-     */
-    public abstract int next(int n);
-
-    /**
-     * Advances the iterator forward one boundary.  The current iteration
-     * position is updated to point to the next boundary position after the
-     * current position, and this is also the value that is returned.  If
-     * the current position is equal to the value returned by last(), or to
-     * DONE, this function returns DONE and sets the current position to
-     * DONE.
-     * @return The position of the first boundary position following the
-     * iteration position.
-     * @stable ICU 2.0
-     */
-    public abstract int next();
-
-    /**
-     * Advances the iterator backward one boundary.  The current iteration
-     * position is updated to point to the last boundary position before
-     * the current position, and this is also the value that is returned.  If
-     * the current position is equal to the value returned by first(), or to
-     * DONE, this function returns DONE and sets the current position to
-     * DONE.
-     * @return The position of the last boundary position preceding the
-     * iteration position.
-     * @stable ICU 2.0
-     */
-    public abstract int previous();
-
-    /**
-     * Sets the iterator's current iteration position to be the first
-     * boundary position following the specified position.  (Whether the
-     * specified position is itself a boundary position or not doesn't
-     * matter-- this function always moves the iteration position to the
-     * first boundary after the specified position.)  If the specified
-     * position is the past-the-end position, returns DONE.
-     * @param offset The character position to start searching from.
-     * @return The position of the first boundary position following
-     * "offset" (whether or not "offset" itself is a boundary position),
-     * or DONE if "offset" is the past-the-end offset.
-     * @stable ICU 2.0
-     */
-    public abstract int following(int offset);
-
-    /**
-     * Sets the iterator's current iteration position to be the last
-     * boundary position preceding the specified position.  (Whether the
-     * specified position is itself a boundary position or not doesn't
-     * matter-- this function always moves the iteration position to the
-     * last boundary before the specified position.)  If the specified
-     * position is the starting position, returns DONE.
-     * @param offset The character position to start searching from.
-     * @return The position of the last boundary position preceding
-     * "offset" (whether of not "offset" itself is a boundary position),
-     * or DONE if "offset" is the starting offset of the iterator.
-     * @stable ICU 2.0
-     */
-    public int preceding(int offset) {
-        // NOTE:  This implementation is here solely because we can't add new
-        // abstract methods to an existing class.  There is almost ALWAYS a
-        // better, faster way to do this.
-        int pos = following(offset);
-        while (pos >= offset && pos != DONE)
-            pos = previous();
-        return pos;
-    }
-
-    /**
-     * Return true if the specfied position is a boundary position.  If the
-     * function returns true, the current iteration position is set to the
-     * specified position; if the function returns false, the current
-     * iteration position is set as though following() had been called.
-     * @param offset the offset to check.
-     * @return True if "offset" is a boundary position.
-     * @stable ICU 2.0
-     */
-    public boolean isBoundary(int offset) {
-        // Again, this is the default implementation, which is provided solely because
-        // we couldn't add a new abstract method to an existing class.  The real
-        // implementations will usually need to do a little more work.
-        if (offset == 0) {
-            return true;
-        }
-        else
-            return following(offset - 1) == offset;
-    }
-
-    /**
-     * Return the iterator's current position.
-     * @return The iterator's current position.
-     * @stable ICU 2.0
-     */
-    public abstract int current();
-
-    /**
-     * Returns a CharacterIterator over the text being analyzed.
-     * For at least some subclasses of BreakIterator, this is a reference
-     * to the <b>actual iterator being used</b> by the BreakIterator,
-     * and therefore, this function's return value should be treated as
-     * <tt>const</tt>.  No guarantees are made about the current position
-     * of this iterator when it is returned.  If you need to move that
-     * position to examine the text, clone this function's return value first.
-     * @return A CharacterIterator over the text being analyzed.
-     * @stable ICU 2.0
-     */
-    public abstract CharacterIterator getText();
-
-    /**
-     * Sets the iterator to analyze a new piece of text.  The new
-     * piece of text is passed in as a String, and the current
-     * iteration position is reset to the beginning of the string.
-     * (The old text is dropped.)
-     * @param newText A String containing the text to analyze with
-     * this BreakIterator.
-     * @stable ICU 2.0
-     */
-    public void setText(String newText)
-    {
-        setText(new StringCharacterIterator(newText));
-    }
-
-    /**
-     * Sets the iterator to analyze a new piece of text.  The
-     * BreakIterator is passed a CharacterIterator through which
-     * it will access the text itself.  The current iteration
-     * position is reset to the CharacterIterator's start index.
-     * (The old iterator is dropped.)
-     * @param newText A CharacterIterator referring to the text
-     * to analyze with this BreakIterator (the iterator's current
-     * position is ignored, but its other state is significant).
-     * @stable ICU 2.0
-     */
-    public abstract void setText(CharacterIterator newText);
-
-    /**
-     * {@icu}
-     * @stable ICU 2.4
-     */
-    public static final int KIND_CHARACTER = 0;
-    /**
-     * {@icu}
-     * @stable ICU 2.4
-     */
-    public static final int KIND_WORD = 1;
-    /** 
-     * {@icu}
-     * @stable ICU 2.4
-     */
-    public static final int KIND_LINE = 2;
-    /** 
-     * {@icu}
-     * @stable ICU 2.4
-     */
-    public static final int KIND_SENTENCE = 3;
-//    /** 
-//     * {@icu}
-//     * @stable ICU 2.4
-//     */
-//    public static final int KIND_TITLE = 4;
-
-    /**
-     * Returns a new instance of BreakIterator that locates word boundaries.
-     * This function assumes that the text being analyzed is in the default
-     * locale's language.
-     * @return An instance of BreakIterator that locates word boundaries.
-     * @stable ICU 2.0
-     */
-    public static BreakIterator getWordInstance()
-    {
-        return getWordInstance(Locale.getDefault());
-    }
-
-    /**
-     * Returns a new instance of BreakIterator that locates word boundaries.
-     * @param where A locale specifying the language of the text to be
-     * analyzed.
-     * @return An instance of BreakIterator that locates word boundaries.
-     * @stable ICU 2.0
-     */
-    public static BreakIterator getWordInstance(Locale where)
-    {
-        return getBreakInstance(where, KIND_WORD);
-    }
-
-    /**
-     * {@icu} Returns a new instance of BreakIterator that locates word boundaries.
-     * @param where A locale specifying the language of the text to be
-     * analyzed.
-     * @return An instance of BreakIterator that locates word boundaries.
-     * @stable ICU 3.2
-     */
-    public static BreakIterator getWordInstance(ULocale where)
-    {
-        return getBreakInstance(where.toLocale(), KIND_WORD);
-    }
-
-    /**
-     * Returns a new instance of BreakIterator that locates legal line-
-     * wrapping positions.  This function assumes the text being broken
-     * is in the default locale's language.
-     * @return A new instance of BreakIterator that locates legal
-     * line-wrapping positions.
-     * @stable ICU 2.0
-     */
-    public static BreakIterator getLineInstance()
-    {
-        return getLineInstance(Locale.getDefault());
-    }
-
-    /**
-     * Returns a new instance of BreakIterator that locates legal line-
-     * wrapping positions.
-     * @param where A Locale specifying the language of the text being broken.
-     * @return A new instance of BreakIterator that locates legal
-     * line-wrapping positions.
-     * @stable ICU 2.0
-     */
-    public static BreakIterator getLineInstance(Locale where)
-    {
-        return getBreakInstance(where, KIND_LINE);
-    }
-
-    /**
-     * {@icu} Returns a new instance of BreakIterator that locates legal line-
-     * wrapping positions.
-     * @param where A Locale specifying the language of the text being broken.
-     * @return A new instance of BreakIterator that locates legal
-     * line-wrapping positions.
-     * @stable ICU 3.2
-     */
-    public static BreakIterator getLineInstance(ULocale where)
-    {
-        return getBreakInstance(where.toLocale(), KIND_LINE);
-    }
-
-    /**
-     * Returns a new instance of BreakIterator that locates logical-character
-     * boundaries.  This function assumes that the text being analyzed is
-     * in the default locale's language.
-     * @return A new instance of BreakIterator that locates logical-character
-     * boundaries.
-     * @stable ICU 2.0
-     */
-    public static BreakIterator getCharacterInstance()
-    {
-        return getCharacterInstance(Locale.getDefault());
-    }
-
-    /**
-     * Returns a new instance of BreakIterator that locates logical-character
-     * boundaries.
-     * @param where A Locale specifying the language of the text being analyzed.
-     * @return A new instance of BreakIterator that locates logical-character
-     * boundaries.
-     * @stable ICU 2.0
-     */
-    public static BreakIterator getCharacterInstance(Locale where)
-    {
-        return getBreakInstance(where, KIND_CHARACTER);
-    }
-
-    /**
-     * {@icu} Returns a new instance of BreakIterator that locates logical-character
-     * boundaries.
-     * @param where A Locale specifying the language of the text being analyzed.
-     * @return A new instance of BreakIterator that locates logical-character
-     * boundaries.
-     * @stable ICU 3.2
-     */
-    public static BreakIterator getCharacterInstance(ULocale where)
-    {
-        return getBreakInstance(where.toLocale(), KIND_CHARACTER);
-    }
-
-    /**
-     * Returns a new instance of BreakIterator that locates sentence boundaries.
-     * This function assumes the text being analyzed is in the default locale's
-     * language.
-     * @return A new instance of BreakIterator that locates sentence boundaries.
-     * @stable ICU 2.0
-     */
-    public static BreakIterator getSentenceInstance()
-    {
-        return getSentenceInstance(Locale.getDefault());
-    }
-
-    /**
-     * Returns a new instance of BreakIterator that locates sentence boundaries.
-     * @param where A Locale specifying the language of the text being analyzed.
-     * @return A new instance of BreakIterator that locates sentence boundaries.
-     * @stable ICU 2.0
-     */
-    public static BreakIterator getSentenceInstance(Locale where)
-    {
-        return getBreakInstance(where, KIND_SENTENCE);
-    }
-
-    /**
-     * {@icu} Returns a new instance of BreakIterator that locates sentence boundaries.
-     * @param where A Locale specifying the language of the text being analyzed.
-     * @return A new instance of BreakIterator that locates sentence boundaries.
-     * @stable ICU 3.2
-     */
-    public static BreakIterator getSentenceInstance(ULocale where)
-    {
-        return getBreakInstance(where.toLocale(), KIND_SENTENCE);
-    }
-
-//    /**
-//     * {@icu} Returns a new instance of BreakIterator that locates title boundaries.
-//     * This function assumes the text being analyzed is in the default locale's
-//     * language. The iterator returned locates title boundaries as described for
-//     * Unicode 3.2 only. For Unicode 4.0 and above title boundary iteration,
-//     * please use a word boundary iterator. {@link #getWordInstance}
-//     * @return A new instance of BreakIterator that locates title boundaries.
-//     * @stable ICU 2.0
-//     */
-//    public static BreakIterator getTitleInstance()
-//    {
-//        return getTitleInstance(Locale.getDefault());
-//    }
-
-//    /**
-//     * {@icu} Returns a new instance of BreakIterator that locates title boundaries.
-//     * The iterator returned locates title boundaries as described for
-//     * Unicode 3.2 only. For Unicode 4.0 and above title boundary iteration,
-//     * please use Word Boundary iterator.{@link #getWordInstance}
-//     * @param where A Locale specifying the language of the text being analyzed.
-//     * @return A new instance of BreakIterator that locates title boundaries.
-//     * @stable ICU 2.0
-//     */
-//    public static BreakIterator getTitleInstance(Locale where)
-//    {
-//        return getBreakInstance(where, KIND_TITLE);
-//    }
-
-//    /**
-//     * {@icu} Returns a new instance of BreakIterator that locates title boundaries.
-//     * The iterator returned locates title boundaries as described for
-//     * Unicode 3.2 only. For Unicode 4.0 and above title boundary iteration,
-//     * please use Word Boundary iterator.{@link #getWordInstance}
-//     * @param where A Locale specifying the language of the text being analyzed.
-//     * @return A new instance of BreakIterator that locates title boundaries.
-//     * @stable ICU 3.2
-//s     */
-//    public static BreakIterator getTitleInstance(ULocale where)
-//    {
-//        return getBreakInstance(where.toLocale(), KIND_TITLE);
-//    }
-
-//    /**
-//     * {@icu} Registers a new break iterator of the indicated kind, to use in the given
-//     * locale.  Clones of the iterator will be returned if a request for a break iterator
-//     * of the given kind matches or falls back to this locale.
-//     * @param iter the BreakIterator instance to adopt.
-//     * @param locale the Locale for which this instance is to be registered
-//     * @param kind the type of iterator for which this instance is to be registered
-//     * @return a registry key that can be used to unregister this instance
-//     * @stable ICU 2.4
-//     */
-//    public static Object registerInstance(BreakIterator iter, Locale locale, int kind) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Registers a new break iterator of the indicated kind, to use in the given
-//     * locale.  Clones of the iterator will be returned if a request for a break iterator
-//     * of the given kind matches or falls back to this locale.
-//     * @param iter the BreakIterator instance to adopt.
-//     * @param locale the Locale for which this instance is to be registered
-//     * @param kind the type of iterator for which this instance is to be registered
-//     * @return a registry key that can be used to unregister this instance
-//     * @stable ICU 3.2
-//     */
-//    public static Object registerInstance(BreakIterator iter, ULocale locale, int kind) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Unregisters a previously-registered BreakIterator using the key returned
-//     * from the register call.  Key becomes invalid after this call and should not be used
-//     * again.
-//     * @param key the registry key returned by a previous call to registerInstance
-//     * @return true if the iterator for the key was successfully unregistered
-//     * @stable ICU 2.4
-//     */
-//    public static boolean unregister(Object key) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    // end of registration
-
-    /**
-     * Returns a particular kind of BreakIterator for a locale.
-     * Avoids writing a switch statement with getXYZInstance(where) calls.
-     * @internal
-     * @deprecated This API is ICU internal only.
-     */
-    public static BreakIterator getBreakInstance(ULocale where, int kind) {
-        return getBreakInstance(where.toLocale(), KIND_SENTENCE);
-    }
-
-    private static BreakIterator getBreakInstance(Locale where, int kind) {
-        java.text.BreakIterator br = null;
-        switch(kind) {
-        case KIND_CHARACTER: br = java.text.BreakIterator.getCharacterInstance(where); break;
-        case KIND_WORD: br = java.text.BreakIterator.getWordInstance(where); break;
-        case KIND_LINE: br = java.text.BreakIterator.getLineInstance(where); break;
-        case KIND_SENTENCE: br = java.text.BreakIterator.getSentenceInstance(where); break;             
-//        case KIND_TITLE: throw new UnsupportedOperationException("Title break is not supported by com.ibm.icu.base");
-        }
-        return new BreakIteratorHandle(br);
-    }
-
-    /**
-     * Returns a list of locales for which BreakIterators can be used.
-     * @return An array of Locales.  All of the locales in the array can
-     * be used when creating a BreakIterator.
-     * @stable ICU 2.6
-     */
-    public static synchronized Locale[] getAvailableLocales() {
-        return java.text.BreakIterator.getAvailableLocales();
-    }
-
-    /**
-     * {@icu} Returns a list of locales for which BreakIterators can be used.
-     * @return An array of Locales.  All of the locales in the array can
-     * be used when creating a BreakIterator.
-     * @draft ICU 3.2 (retain)
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static synchronized ULocale[] getAvailableULocales() {
-        Locale[] locales = java.text.BreakIterator.getAvailableLocales();
-        ULocale[] ulocales = new ULocale[locales.length];
-        for (int i = 0; i < locales.length; ++i) {
-            ulocales[i] = ULocale.forLocale(locales[i]);
-        }
-        return ulocales;
-    }
-
-//    /**
-//     * {@icu} Returns the locale that was used to create this object, or null.
-//     * This may may differ from the locale requested at the time of
-//     * this object's creation.  For example, if an object is created
-//     * for locale <tt>en_US_CALIFORNIA</tt>, the actual data may be
-//     * drawn from <tt>en</tt> (the <i>actual</i> locale), and
-//     * <tt>en_US</tt> may be the most specific locale that exists (the
-//     * <i>valid</i> locale).
-//     *
-//     * <p>Note: The <i>actual</i> locale is returned correctly, but the <i>valid</i>
-//     * locale is not, in most cases.
-//     * @param type type of information requested, either {@link
-//     * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link
-//     * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}.
-//     * @return the information specified by <i>type</i>, or null if
-//     * this object was not constructed from locale data.
-//     * @see com.ibm.icu.util.ULocale
-//     * @see com.ibm.icu.util.ULocale#VALID_LOCALE
-//     * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
-//     * @draft ICU 2.8 (retain)
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public final ULocale getLocale(ULocale.Type type) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    // forwarding implementation class
-    static final class BreakIteratorHandle extends BreakIterator {
-        /**
-         * @internal
-         */
-        public final java.text.BreakIterator breakIterator;
-
-        /**
-         * @internal
-         * @param delegate the BreakIterator to which to delegate
-         */
-        public BreakIteratorHandle(java.text.BreakIterator delegate) {
-            this.breakIterator = delegate;
-        }
-
-        public int first() {
-            return breakIterator.first();
-        }
-        public int last() {
-            return breakIterator.last();
-        }
-        public int next(int n) {
-            return breakIterator.next(n);
-        }
-        public int next() {
-            return breakIterator.next();
-        }
-        public int previous() {
-            return breakIterator.previous();
-        }
-        public int following(int offset) {
-            return breakIterator.following(offset);
-        }
-        public int preceding(int offset) {
-            return breakIterator.preceding(offset);
-        }
-        public boolean isBoundary(int offset) {
-            return breakIterator.isBoundary(offset);
-        }
-        public int current() {
-            return breakIterator.current();
-        }
-        public CharacterIterator getText() {
-            return breakIterator.getText();
-        }
-        public void setText(CharacterIterator newText) {
-            breakIterator.setText(newText);
-        }
-
-        /**
-         * Return a string suitable for debugging.
-         * @return a string suitable for debugging
-         * @stable ICU 3.4.3
-         */
-        public String toString() {
-            return breakIterator.toString();
-        }
-
-        /**
-         * Return a clone of this BreakIterator.
-         * @return a clone of this BreakIterator
-         * @stable ICU 3.4.3
-         */
-        public Object clone() {
-            return new BreakIteratorHandle((java.text.BreakIterator)breakIterator.clone());
-        }
-
-        /**
-         * Return true if rhs is a BreakIterator with the same break behavior as this.
-         * @return true if rhs equals this
-         * @stable ICU 3.4.3
-         */
-        public boolean equals(Object rhs) {
-            try {
-                return breakIterator.equals(((BreakIteratorHandle)rhs).breakIterator);
-            }
-            catch (Exception e) {
-                return false;
-            }
-        }
-
-        /**
-         * Return a hashCode.
-         * @return a hashCode
-         * @stable ICU 3.4.3
-         */
-        public int hashCode() {
-            return breakIterator.hashCode();
-        }
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/CollationKey.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/CollationKey.java
deleted file mode 100644
index 78fbe79..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/CollationKey.java
+++ /dev/null
@@ -1,417 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/**
-*******************************************************************************
-* Copyright (C) 1996-2012, International Business Machines Corporation and    *
-* others. All Rights Reserved.                                                *
-*******************************************************************************
-*/
-package com.ibm.icu.text;
-
-/**
- * <p>A <code>CollationKey</code> represents a <code>String</code>
- * under the rules of a specific <code>Collator</code>
- * object. Comparing two <code>CollationKey</code>s returns the
- * relative order of the <code>String</code>s they represent.</p>
- *
- * <p>Since the rule set of <code>Collator</code>s can differ, the
- * sort orders of the same string under two different
- * <code>Collator</code>s might differ.  Hence comparing
- * <code>CollationKey</code>s generated from different
- * <code>Collator</code>s can give incorrect results.</p>
- 
- * <p>Both the method
- * <code>CollationKey.compareTo(CollationKey)</code> and the method
- * <code>Collator.compare(String, String)</code> compare two strings
- * and returns their relative order.  The performance characteristics
- * of these two approaches can differ.</p>
- *
- * <p>During the construction of a <code>CollationKey</code>, the
- * entire source string is examined and processed into a series of
- * bits terminated by a null, that are stored in the <code>CollationKey</code>. 
- * When <code>CollationKey.compareTo(CollationKey)</code> executes, it
- * performs bitwise comparison on the bit sequences.  This can incurs
- * startup cost when creating the <code>CollationKey</code>, but once
- * the key is created, binary comparisons are fast.  This approach is
- * recommended when the same strings are to be compared over and over
- * again.</p>
- *
- * <p>On the other hand, implementations of
- * <code>Collator.compare(String, String)</code> can examine and
- * process the strings only until the first characters differing in
- * order.  This approach is recommended if the strings are to be
- * compared only once.</p>
- * 
- * <p>More information about the composition of the bit sequence can
- * be found in the 
- * <a href="http://www.icu-project.org/userguide/Collate_ServiceArchitecture.html">
- * user guide</a>.</p>
- *
- * <p>The following example shows how <code>CollationKey</code>s can be used
- * to sort a list of <code>String</code>s.</p>
- * <blockquote>
- * <pre>
- * // Create an array of CollationKeys for the Strings to be sorted.
- * Collator myCollator = Collator.getInstance();
- * CollationKey[] keys = new CollationKey[3];
- * keys[0] = myCollator.getCollationKey("Tom");
- * keys[1] = myCollator.getCollationKey("Dick");
- * keys[2] = myCollator.getCollationKey("Harry");
- * sort( keys );
- * <br>
- * //...
- * <br>
- * // Inside body of sort routine, compare keys this way
- * if( keys[i].compareTo( keys[j] ) > 0 )
- *    // swap keys[i] and keys[j]
- * <br>
- * //...
- * <br>
- * // Finally, when we've returned from sort.
- * System.out.println( keys[0].getSourceString() );
- * System.out.println( keys[1].getSourceString() );
- * System.out.println( keys[2].getSourceString() );
- * </pre>
- * </blockquote>
- * </p>
- * <p>
- * This class is not subclassable
- * </p>
- * @see Collator
- * @see RuleBasedCollator
- * @author Syn Wee Quek
- * @stable ICU 2.8 
- */
-public final class CollationKey implements Comparable<CollationKey>
-{
-    /**
-     * @internal
-     */
-    final java.text.CollationKey key;
-
-    /**
-     * @internal
-     */
-    CollationKey(java.text.CollationKey delegate) {
-        this.key = delegate;
-    }
-
-    // public inner classes -------------------------------------------------
-    
-//    /** 
-//     * Options that used in the API CollationKey.getBound() for getting a 
-//     * CollationKey based on the bound mode requested.
-//     * @stable ICU 2.6
-//     */
-//    public static final class BoundMode 
-//    {
-//        /*
-//         * do not change the values assigned to the members of this enum. 
-//         * Underlying code depends on them having these numbers  
-//         */
-//         
-//        /** 
-//         * Lower bound
-//         * @stable ICU 2.6
-//         */
-//        public static final int LOWER = 0;
-//
-//        /** 
-//         * Upper bound that will match strings of exact size
-//         * @stable ICU 2.6
-//         */
-//        public static final int UPPER = 1;
-//
-//        /** 
-//         * Upper bound that will match all the strings that have the same 
-//         * initial substring as the given string
-//         * @stable ICU 2.6
-//         */
-//        public static final int UPPER_LONG = 2;
-//
-//        /**
-//         * Number of bound mode
-//         * @stable ICU 2.6
-//         */
-//        public static final int COUNT = 3;
-//        
-//        /**
-//         * Private Constructor
-//         */
-//        ///CLOVER:OFF
-//        private BoundMode(){}
-//        ///CLOVER:ON
-//    }
-    
-    // public constructor ---------------------------------------------------
-    
-//    /**
-//     * CollationKey constructor.
-//     * This constructor is given public access, unlike the JDK version, to
-//     * allow access to users extending the Collator class. See 
-//     * {@link Collator#getCollationKey(String)}. 
-//     * @param source string this CollationKey is to represent
-//     * @param key array of bytes that represent the collation order of argument
-//     *            source terminated by a null
-//     * @see Collator
-//     * @stable ICU 2.8
-//     */
-//    public CollationKey(String source, byte key[])
-//    {
-//        throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * CollationKey constructor that forces key to release its internal byte 
-//     * array for adoption. key will have a null byte array after this 
-//     * construction.
-//     * @param source string this CollationKey is to represent
-//     * @param key RawCollationKey object that represents the collation order of 
-//     *            argument source. 
-//     * @see Collator
-//     * @see RawCollationKey
-//     * @stable ICU 2.8 
-//     */
-//    public CollationKey(String source, RawCollationKey key)
-//    {
-//        throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base");
-//    }
-
-    // public getters -------------------------------------------------------
-    
-    /**
-     * Return the source string that this CollationKey represents.
-     * @return source string that this CollationKey represents
-     * @stable ICU 2.8
-     */
-    public String getSourceString() 
-    {
-        return key.getSourceString();
-    }
-
-    /**
-     * <p>Duplicates and returns the value of this CollationKey as a sequence 
-     * of big-endian bytes terminated by a null.</p> 
-     *
-     * <p>If two CollationKeys can be legitimately compared, then one can
-     * compare the byte arrays of each to obtain the same result, e.g.
-     * <pre>
-     * byte key1[] = collationkey1.toByteArray();
-     * byte key2[] = collationkey2.toByteArray();
-     * int key, targetkey;
-     * int i = 0;
-     * do {
-     *       key = key1[i] & 0xFF;
-     *     targetkey = key2[i] & 0xFF;
-     *     if (key &lt; targetkey) {
-     *         System.out.println("String 1 is less than string 2");
-     *         return;
-     *     }
-     *     if (targetkey &lt; key) {
-     *         System.out.println("String 1 is more than string 2");
-     *     }
-     *     i ++;
-     * } while (key != 0 && targetKey != 0);
-     *
-     * System.out.println("Strings are equal.");
-     * </pre>
-     * </p>  
-     * @return CollationKey value in a sequence of big-endian byte bytes 
-     *         terminated by a null.
-     * @stable ICU 2.8
-     */
-    public byte[] toByteArray() 
-    {
-        return key.toByteArray();
-    }
-
-    // public other methods -------------------------------------------------    
-     
-    /**
-     * <p>Compare this CollationKey to another CollationKey.  The
-     * collation rules of the Collator that created this key are
-     * applied.</p>
-     *
-     * <p><strong>Note:</strong> Comparison between CollationKeys
-     * created by different Collators might return incorrect
-     * results.  See class documentation.</p>
-     *
-     * @param target target CollationKey
-     * @return an integer value.  If the value is less than zero this CollationKey
-     *         is less than than target, if the value is zero they are equal, and
-     *         if the value is greater than zero this CollationKey is greater 
-     *         than target.
-     * @exception NullPointerException is thrown if argument is null.
-     * @see Collator#compare(String, String)
-     * @stable ICU 2.8 
-     */
-    public int compareTo(CollationKey target)
-    {
-    	return key.compareTo(target.key);
-    }
-
-    /**
-     * <p>Compare this CollationKey and the specified Object for
-     * equality.  The collation rules of the Collator that created
-     * this key are applied.</p>
-     *
-     * <p>See note in compareTo(CollationKey) for warnings about
-     * possible incorrect results.</p>
-     *
-     * @param target the object to compare to.
-     * @return true if the two keys compare as equal, false otherwise.
-     * @see #compareTo(CollationKey)
-     * @exception ClassCastException is thrown when the argument is not 
-     *            a CollationKey.  NullPointerException is thrown when the argument 
-     *            is null.
-     * @stable ICU 2.8 
-     */
-    public boolean equals(Object target) 
-    {
-        if (!(target instanceof CollationKey)) {
-            return false;
-        }
-        
-        return equals((CollationKey)target);
-    }
-    
-    /**
-     * <p>
-     * Compare this CollationKey and the argument target CollationKey for 
-     * equality.
-     * The collation 
-     * rules of the Collator object which created these objects are applied.
-     * </p>
-     * <p>
-     * See note in compareTo(CollationKey) for warnings of incorrect results
-     * </p>
-     * @param target the CollationKey to compare to.
-     * @return true if two objects are equal, false otherwise.
-     * @exception NullPointerException is thrown when the argument is null.
-     * @stable ICU 2.8
-     */
-    public boolean equals(CollationKey target) 
-    {
-    	return key.equals(target.key);
-    }
-
-    /**
-     * <p>Returns a hash code for this CollationKey. The hash value is calculated 
-     * on the key itself, not the String from which the key was created. Thus 
-     * if x and y are CollationKeys, then x.hashCode(x) == y.hashCode() 
-     * if x.equals(y) is true. This allows language-sensitive comparison in a 
-     * hash table.
-     * </p>
-     * @return the hash value.
-     * @stable ICU 2.8
-     */
-    public int hashCode() 
-    {
-    	return key.hashCode();
-    }
-    
-//    /**
-//     * <p>
-//     * Produce a bound for the sort order of a given collation key and a 
-//     * strength level. This API does not attempt to find a bound for the 
-//     * CollationKey String representation, hence null will be returned in its 
-//     * place.
-//     * </p>
-//     * <p>
-//     * Resulting bounds can be used to produce a range of strings that are
-//     * between upper and lower bounds. For example, if bounds are produced
-//     * for a sortkey of string "smith", strings between upper and lower 
-//     * bounds with primary strength would include "Smith", "SMITH", "sMiTh".
-//     * </p>
-//     * <p>
-//     * There are two upper bounds that can be produced. If BoundMode.UPPER
-//     * is produced, strings matched would be as above. However, if a bound
-//     * is produced using BoundMode.UPPER_LONG is used, the above example will
-//     * also match "Smithsonian" and similar.
-//     * </p>
-//     * <p>
-//     * For more on usage, see example in test procedure 
-//     * <a href="http://source.icu-project.org/repos/icu/icu4j/trunk/src/com/ibm/icu/dev/test/collator/CollationAPITest.java">
-//     * src/com/ibm/icu/dev/test/collator/CollationAPITest/TestBounds.
-//     * </a>
-//     * </p>
-//     * <p>
-//     * Collation keys produced may be compared using the <TT>compare</TT> API.
-//     * </p>
-//     * @param boundType Mode of bound required. It can be BoundMode.LOWER, which 
-//     *              produces a lower inclusive bound, BoundMode.UPPER, that 
-//     *              produces upper bound that matches strings of the same 
-//     *              length or BoundMode.UPPER_LONG that matches strings that 
-//     *              have the same starting substring as the source string.
-//     * @param noOfLevels Strength levels required in the resulting bound 
-//     *                 (for most uses, the recommended value is PRIMARY). This
-//     *                 strength should be less than the maximum strength of 
-//     *                 this CollationKey.
-//     *                 See users guide for explanation on the strength levels a 
-//     *                 collation key can have. 
-//     * @return the result bounded CollationKey with a valid sort order but 
-//     *         a null String representation.
-//     * @exception IllegalArgumentException thrown when the strength level 
-//     *            requested is higher than or equal to the strength in this
-//     *            CollationKey. 
-//     *            In the case of an Exception, information 
-//     *            about the maximum strength to use will be returned in the 
-//     *            Exception. The user can then call getBound() again with the 
-//     *            appropriate strength.
-//     * @see CollationKey
-//     * @see CollationKey.BoundMode
-//     * @see Collator#PRIMARY
-//     * @see Collator#SECONDARY
-//     * @see Collator#TERTIARY
-//     * @see Collator#QUATERNARY
-//     * @see Collator#IDENTICAL
-//     * @stable ICU 2.6
-//     */
-//    public CollationKey getBound(int boundType, int noOfLevels) 
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-    
-    /** 
-     * <p>
-     * Merges this CollationKey with another. Only the sorting order of the 
-     * CollationKeys will be merged. This API does not attempt to merge the 
-     * String representations of the CollationKeys, hence null will be returned
-     * as the String representation.
-     * </p>
-     * <p>
-     * The strength levels are merged with their corresponding counterparts 
-     * (PRIMARIES with PRIMARIES, SECONDARIES with SECONDARIES etc.). 
-     * </p>
-     * <p>
-     * The merged String representation of the result CollationKey will be a
-     * concatenation of the String representations of the 2 source 
-     * CollationKeys.
-     * </p>
-     * <p>
-     * Between the values from the same level a separator is inserted.
-     * example (uncompressed):
-     * <pre> 
-     * 191B1D 01 050505 01 910505 00 and 1F2123 01 050505 01 910505 00
-     * will be merged as 
-     * 191B1D 02 1F212301 050505 02 050505 01 910505 02 910505 00
-     * </pre>
-     * </p>
-     * <p>
-     * This allows for concatenating of first and last names for sorting, among 
-     * other things.
-     * </p>
-     * </p>
-     * @param source CollationKey to merge with 
-     * @return a CollationKey that contains the valid merged sorting order 
-     *         with a null String representation, 
-     *         i.e. <tt>new CollationKey(null, merge_sort_order)</tt>
-     * @exception IllegalArgumentException thrown if source CollationKey
-     *            argument is null or of 0 length.
-     * @stable ICU 2.6
-     */
-    public CollationKey merge(CollationKey source)
-    {
-        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Collator.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Collator.java
deleted file mode 100644
index 7596db3..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/Collator.java
+++ /dev/null
@@ -1,1020 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/**
-*******************************************************************************
-* Copyright (C) 1996-2012, International Business Machines Corporation and    *
-* others. All Rights Reserved.                                                *
-*******************************************************************************
-*/
-package com.ibm.icu.text;
-
-import java.text.RuleBasedCollator;
-import java.util.Comparator;
-import java.util.Locale;
-
-import com.ibm.icu.util.ULocale;
-
-/**
-* {@icuenhanced java.text.Collator}.{@icu _usage_}
-*
-* <p>Collator performs locale-sensitive string comparison. A concrete
-* subclass, RuleBasedCollator, allows customization of the collation
-* ordering by the use of rule sets.</p>
-*
-* <p>Following the <a href=http://www.unicode.org>Unicode
-* Consortium</a>'s specifications for the
-* <a href="http://www.unicode.org/unicode/reports/tr10/">Unicode Collation
-* Algorithm (UCA)</a>, there are 5 different levels of strength used
-* in comparisons:
-*
-* <ul>
-* <li>PRIMARY strength: Typically, this is used to denote differences between
-*     base characters (for example, "a" &lt; "b").
-*     It is the strongest difference. For example, dictionaries are divided
-*     into different sections by base character.
-* <li>SECONDARY strength: Accents in the characters are considered secondary
-*     differences (for example, "as" &lt; "&agrave;s" &lt; "at"). Other
-*     differences
-*     between letters can also be considered secondary differences, depending
-*     on the language. A secondary difference is ignored when there is a
-*     primary difference anywhere in the strings.
-* <li>TERTIARY strength: Upper and lower case differences in characters are
-*     distinguished at tertiary strength (for example, "ao" &lt; "Ao" &lt;
-*     "a&ograve;"). In addition, a variant of a letter differs from the base
-*     form on the tertiary strength (such as "A" and "&#9398;"). Another
-*     example is the
-*     difference between large and small Kana. A tertiary difference is ignored
-*     when there is a primary or secondary difference anywhere in the strings.
-* <li>QUATERNARY strength: When punctuation is ignored
-*     <a href="http://www.icu-project.org/userguide/Collate_Concepts.html#Ignoring_Punctuation">
-*     (see Ignoring Punctuations in the user guide)</a> at PRIMARY to TERTIARY
-*     strength, an additional strength level can
-*     be used to distinguish words with and without punctuation (for example,
-*     "ab" &lt; "a-b" &lt; "aB").
-*     This difference is ignored when there is a PRIMARY, SECONDARY or TERTIARY
-*     difference. The QUATERNARY strength should only be used if ignoring
-*     punctuation is required.
-* <li>IDENTICAL strength:
-*     When all other strengths are equal, the IDENTICAL strength is used as a
-*     tiebreaker. The Unicode code point values of the NFD form of each string
-*     are compared, just in case there is no difference.
-*     For example, Hebrew cantillation marks are only distinguished at this
-*     strength. This strength should be used sparingly, as only code point
-*     value differences between two strings is an extremely rare occurrence.
-*     Using this strength substantially decreases the performance for both
-*     comparison and collation key generation APIs. This strength also
-*     increases the size of the collation key.
-* </ul>
-*
-* Unlike the JDK, ICU4J's Collator deals only with 2 decomposition modes,
-* the canonical decomposition mode and one that does not use any decomposition.
-* The compatibility decomposition mode, java.text.Collator.FULL_DECOMPOSITION
-* is not supported here. If the canonical
-* decomposition mode is set, the Collator handles un-normalized text properly,
-* producing the same results as if the text were normalized in NFD. If
-* canonical decomposition is turned off, it is the user's responsibility to
-* ensure that all text is already in the appropriate form before performing
-* a comparison or before getting a CollationKey.</p>
-*
-* <p>For more information about the collation service see the
-* <a href="http://www.icu-project.org/userguide/Collate_Intro.html">users
-* guide</a>.</p>
-*
-* <p>Examples of use
-* <pre>
-* // Get the Collator for US English and set its strength to PRIMARY
-* Collator usCollator = Collator.getInstance(Locale.US);
-* usCollator.setStrength(Collator.PRIMARY);
-* if (usCollator.compare("abc", "ABC") == 0) {
-*     System.out.println("Strings are equivalent");
-* }
-*
-* The following example shows how to compare two strings using the
-* Collator for the default locale.
-*
-* // Compare two strings in the default locale
-* Collator myCollator = Collator.getInstance();
-* myCollator.setDecomposition(NO_DECOMPOSITION);
-* if (myCollator.compare("&agrave;&#92;u0325", "a&#92;u0325&#768;") != 0) {
-*     System.out.println("&agrave;&#92;u0325 is not equals to a&#92;u0325&#768; without decomposition");
-*     myCollator.setDecomposition(CANONICAL_DECOMPOSITION);
-*     if (myCollator.compare("&agrave;&#92;u0325", "a&#92;u0325&#768;") != 0) {
-*         System.out.println("Error: &agrave;&#92;u0325 should be equals to a&#92;u0325&#768; with decomposition");
-*     }
-*     else {
-*         System.out.println("&agrave;&#92;u0325 is equals to a&#92;u0325&#768; with decomposition");
-*     }
-* }
-* else {
-*     System.out.println("Error: &agrave;&#92;u0325 should be not equals to a&#92;u0325&#768; without decomposition");
-* }
-* </pre>
-* </p>
-* @see RuleBasedCollator
-* @see CollationKey
-* @author Syn Wee Quek
-* @stable ICU 2.8
-*/
-public class Collator implements Comparator<Object>, Cloneable
-{
-    /**
-     * @internal
-     */
-    private final java.text.Collator collator;
-
-    /**
-     * @internal
-     */
-    private Collator(java.text.Collator delegate) {
-        this.collator = delegate;
-    }
-
-    /**
-     * Create a collator with a null delegate.
-     * For use by possible subclassers.  This is present since
-     * the original Collator is abstract, and so, in theory
-     * subclassable.  All member APIs must be overridden.
-     */
-    protected Collator() {
-        this.collator = null;
-    }
-
-    // public data members ---------------------------------------------------
-
-    /**
-     * Strongest collator strength value. Typically used to denote differences
-     * between base characters. See class documentation for more explanation.
-     * @see #setStrength
-     * @see #getStrength
-     * @stable ICU 2.8
-     */
-    public final static int PRIMARY = java.text.Collator.PRIMARY;
-
-    /**
-     * Second level collator strength value.
-     * Accents in the characters are considered secondary differences.
-     * Other differences between letters can also be considered secondary
-     * differences, depending on the language.
-     * See class documentation for more explanation.
-     * @see #setStrength
-     * @see #getStrength
-     * @stable ICU 2.8
-     */
-    public final static int SECONDARY = java.text.Collator.SECONDARY;
-
-    /**
-     * Third level collator strength value.
-     * Upper and lower case differences in characters are distinguished at this
-     * strength level. In addition, a variant of a letter differs from the base
-     * form on the tertiary level.
-     * See class documentation for more explanation.
-     * @see #setStrength
-     * @see #getStrength
-     * @stable ICU 2.8
-     */
-    public final static int TERTIARY = java.text.Collator.TERTIARY;
-
-    /**
-     * {@icu} Fourth level collator strength value.
-     * When punctuation is ignored
-     * <a href="http://www.icu-project.org/userguide/Collate_Concepts.html#Ignoring_Punctuation">
-     * (see Ignoring Punctuations in the user guide)</a> at PRIMARY to TERTIARY
-     * strength, an additional strength level can
-     * be used to distinguish words with and without punctuation.
-     * See class documentation for more explanation.
-     * @see #setStrength
-     * @see #getStrength
-     * @stable ICU 2.8
-     */
-    public final static int QUATERNARY = java.text.Collator.IDENTICAL;
-
-    /**
-     * Smallest Collator strength value. When all other strengths are equal,
-     * the IDENTICAL strength is used as a tiebreaker. The Unicode code point
-     * values of the NFD form of each string are compared, just in case there
-     * is no difference.
-     * See class documentation for more explanation.
-     * </p>
-     * <p>
-     * Note this value is different from JDK's
-     * </p>
-     * @stable ICU 2.8
-     */
-    public final static int IDENTICAL = java.text.Collator.FULL_DECOMPOSITION;
-
-    /**
-     * {@icunote} This is for backwards compatibility with Java APIs only.  It
-     * should not be used, IDENTICAL should be used instead.  ICU's
-     * collation does not support Java's FULL_DECOMPOSITION mode.
-     * @stable ICU 3.4
-     */
-    public final static int FULL_DECOMPOSITION = java.text.Collator.FULL_DECOMPOSITION;
-
-    /**
-     * Decomposition mode value. With NO_DECOMPOSITION set, Strings
-     * will not be decomposed for collation. This is the default
-     * decomposition setting unless otherwise specified by the locale
-     * used to create the Collator.</p>
-     *
-     * <p><strong>Note</strong> this value is different from the JDK's.</p>
-     * @see #CANONICAL_DECOMPOSITION
-     * @see #getDecomposition
-     * @see #setDecomposition
-     * @stable ICU 2.8
-     */
-    public final static int NO_DECOMPOSITION = java.text.Collator.NO_DECOMPOSITION;
-
-    /**
-     * Decomposition mode value. With CANONICAL_DECOMPOSITION set,
-     * characters that are canonical variants according to the Unicode standard
-     * will be decomposed for collation.</p>
-     *
-     * <p>CANONICAL_DECOMPOSITION corresponds to Normalization Form D as
-     * described in <a href="http://www.unicode.org/unicode/reports/tr15/">
-     * Unicode Technical Report #15</a>.
-     * </p>
-     * @see #NO_DECOMPOSITION
-     * @see #getDecomposition
-     * @see #setDecomposition
-     * @stable ICU 2.8
-     */
-    public final static int CANONICAL_DECOMPOSITION = java.text.Collator.CANONICAL_DECOMPOSITION;
-
-    // public methods --------------------------------------------------------
-
-    // public setters --------------------------------------------------------
-
-    /**
-     * Sets this Collator's strength property. The strength property
-     * determines the minimum level of difference considered significant
-     * during comparison.</p>
-     *
-     * <p>The default strength for the Collator is TERTIARY, unless specified
-     * otherwise by the locale used to create the Collator.</p>
-     *
-     * <p>See the Collator class description for an example of use.</p>
-     * @param newStrength the new strength value.
-     * @see #getStrength
-     * @see #PRIMARY
-     * @see #SECONDARY
-     * @see #TERTIARY
-     * @see #QUATERNARY
-     * @see #IDENTICAL
-     * @throws IllegalArgumentException if the new strength value is not one
-     *                of PRIMARY, SECONDARY, TERTIARY, QUATERNARY or IDENTICAL.
-     * @stable ICU 2.8
-     */
-    public void setStrength(int newStrength)
-    {
-        if (isFrozen) {
-            throw new UnsupportedOperationException("Attempt to modify a frozen Collator instance.");
-        }
-        collator.setStrength(newStrength);
-    }
-
-    /**
-     * Sets the decomposition mode of this Collator.  Setting this
-     * decomposition property with CANONICAL_DECOMPOSITION allows the
-     * Collator to handle un-normalized text properly, producing the
-     * same results as if the text were normalized. If
-     * NO_DECOMPOSITION is set, it is the user's responsibility to
-     * insure that all text is already in the appropriate form before
-     * a comparison or before getting a CollationKey. Adjusting
-     * decomposition mode allows the user to select between faster and
-     * more complete collation behavior.</p>
-     *
-     * <p>Since a great many of the world's languages do not require
-     * text normalization, most locales set NO_DECOMPOSITION as the
-     * default decomposition mode.</p>
-     *
-     * The default decompositon mode for the Collator is
-     * NO_DECOMPOSITON, unless specified otherwise by the locale used
-     * to create the Collator.</p>
-     *
-     * <p>See getDecomposition for a description of decomposition
-     * mode.</p>
-     *
-     * @param decomposition the new decomposition mode
-     * @see #getDecomposition
-     * @see #NO_DECOMPOSITION
-     * @see #CANONICAL_DECOMPOSITION
-     * @throws IllegalArgumentException If the given value is not a valid
-     *            decomposition mode.
-     * @stable ICU 2.8
-     */
-    public void setDecomposition(int decomposition)
-    {
-        if (isFrozen) {
-            throw new UnsupportedOperationException("Attempt to modify a frozen Collator instance.");
-        }
-        collator.setDecomposition(decomposition);
-    }
-
-    // public getters --------------------------------------------------------
-
-    /**
-     * Returns the Collator for the current default locale.
-     * The default locale is determined by java.util.Locale.getDefault().
-     * @return the Collator for the default locale (for example, en_US) if it
-     *         is created successfully. Otherwise if there is no Collator
-     *         associated with the current locale, the default UCA collator
-     *         will be returned.
-     * @see java.util.Locale#getDefault()
-     * @see #getInstance(Locale)
-     * @stable ICU 2.8
-     */
-    public static final Collator getInstance()
-    {
-        return new Collator(java.text.Collator.getInstance());
-    }
-
-    /**
-     * Clones the collator.
-     * @stable ICU 2.6
-     * @return a clone of this collator.
-     */
-    public Object clone() throws CloneNotSupportedException {
-        return new Collator((java.text.Collator)collator.clone());
-    }
-
-    // Freezable interface implementation -------------------------------------------------
-
-    private transient boolean isFrozen = false;
-
-    /**
-     * Determines whether the object has been frozen or not.
-     * @draft ICU 4.8
-     */
-    public boolean isFrozen() {
-        return isFrozen;
-    }
-
-    /**
-     * Freezes the collator.
-     * @return the collator itself.
-     * @draft ICU 4.8
-     */
-    public Collator freeze() {
-        isFrozen = true;
-        return this;
-    }
-
-    /**
-     * Provides for the clone operation. Any clone is initially unfrozen.
-     * @draft ICU 4.8
-     */
-    public Collator cloneAsThawed() {
-        try {
-            Collator other = (Collator) super.clone();
-            other.isFrozen = false;
-            return other;
-        } catch (CloneNotSupportedException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    // begin registry stuff
-
-//    /**
-//     * A factory used with registerFactory to register multiple collators and provide
-//     * display names for them.  If standard locale display names are sufficient,
-//     * Collator instances may be registered instead.
-//     * <p><b>Note:</b> as of ICU4J 3.2, the default API for CollatorFactory uses
-//     * ULocale instead of Locale.  Instead of overriding createCollator(Locale),
-//     * new implementations should override createCollator(ULocale).  Note that
-//     * one of these two methods <b>MUST</b> be overridden or else an infinite
-//     * loop will occur.
-//     * @stable ICU 2.6
-//     */
-//    public static abstract class CollatorFactory {
-//        /**
-//         * Return true if this factory will be visible.  Default is true.
-//         * If not visible, the locales supported by this factory will not
-//         * be listed by getAvailableLocales.
-//         *
-//         * @return true if this factory is visible
-//         * @stable ICU 2.6
-//         */
-//        public boolean visible() {
-//            return true;
-//        }
-//
-//        /**
-//         * Return an instance of the appropriate collator.  If the locale
-//         * is not supported, return null.
-//         * <b>Note:</b> as of ICU4J 3.2, implementations should override
-//         * this method instead of createCollator(Locale).
-//         * @param loc the locale for which this collator is to be created.
-//         * @return the newly created collator.
-//         * @stable ICU 3.2
-//         */
-//        public Collator createCollator(ULocale loc) {
-//            return createCollator(loc.toLocale());
-//        }
-//
-//        /**
-//         * Return an instance of the appropriate collator.  If the locale
-//         * is not supported, return null.
-//         * <p><b>Note:</b> as of ICU4J 3.2, implementations should override
-//         * createCollator(ULocale) instead of this method, and inherit this
-//         * method's implementation.  This method is no longer abstract
-//         * and instead delegates to createCollator(ULocale).
-//         * @param loc the locale for which this collator is to be created.
-//         * @return the newly created collator.
-//         * @stable ICU 2.6
-//         */
-//         public Collator createCollator(Locale loc) {
-//            return createCollator(ULocale.forLocale(loc));
-//        }
-//
-//        /**
-//         * Return the name of the collator for the objectLocale, localized for the displayLocale.
-//         * If objectLocale is not visible or not defined by the factory, return null.
-//         * @param objectLocale the locale identifying the collator
-//         * @param displayLocale the locale for which the display name of the collator should be localized
-//         * @return the display name
-//         * @stable ICU 2.6
-//         */
-//        public String getDisplayName(Locale objectLocale, Locale displayLocale) {
-//            return getDisplayName(ULocale.forLocale(objectLocale), ULocale.forLocale(displayLocale));
-//        }
-//
-//        /**
-//         * Return the name of the collator for the objectLocale, localized for the displayLocale.
-//         * If objectLocale is not visible or not defined by the factory, return null.
-//         * @param objectLocale the locale identifying the collator
-//         * @param displayLocale the locale for which the display name of the collator should be localized
-//         * @return the display name
-//         * @stable ICU 3.2
-//         */
-//        public String getDisplayName(ULocale objectLocale, ULocale displayLocale) {
-//            if (visible()) {
-//                Set<String> supported = getSupportedLocaleIDs();
-//                String name = objectLocale.getBaseName();
-//                if (supported.contains(name)) {
-//                    return objectLocale.getDisplayName(displayLocale);
-//                }
-//            }
-//            return null;
-//        }
-//
-//        /**
-//         * Return an unmodifiable collection of the locale names directly
-//         * supported by this factory.
-//         *
-//         * @return the set of supported locale IDs.
-//         * @stable ICU 2.6
-//         */
-//        public abstract Set<String> getSupportedLocaleIDs();
-//
-//        /**
-//         * Empty default constructor.
-//         * @stable ICU 2.6
-//         */
-//        protected CollatorFactory() {
-//        }
-//    }
-
-    /**
-     * {@icu} Returns the Collator for the desired locale.
-     * @param locale the desired locale.
-     * @return Collator for the desired locale if it is created successfully.
-     *         Otherwise if there is no Collator
-     *         associated with the current locale, a default UCA collator will
-     *         be returned.
-     * @see java.util.Locale
-     * @see java.util.ResourceBundle
-     * @see #getInstance(Locale)
-     * @see #getInstance()
-     * @stable ICU 3.0
-     */
-    public static final Collator getInstance(ULocale locale) {
-        return getInstance(locale.toLocale());
-    }
-
-    /**
-     * Returns the Collator for the desired locale.
-     * @param locale the desired locale.
-     * @return Collator for the desired locale if it is created successfully.
-     *         Otherwise if there is no Collator
-     *         associated with the current locale, a default UCA collator will
-     *         be returned.
-     * @see java.util.Locale
-     * @see java.util.ResourceBundle
-     * @see #getInstance(ULocale)
-     * @see #getInstance()
-     * @stable ICU 2.8
-     */
-    public static final Collator getInstance(Locale locale) {
-        return new Collator(java.text.Collator.getInstance(locale));
-    }
-
-//    /**
-//     * {@icu} Registers a collator as the default collator for the provided locale.  The
-//     * collator should not be modified after it is registered.
-//     *
-//     * @param collator the collator to register
-//     * @param locale the locale for which this is the default collator
-//     * @return an object that can be used to unregister the registered collator.
-//     *
-//     * @stable ICU 3.2
-//     */
-//    public static final Object registerInstance(Collator collator, ULocale locale) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Registers a collator factory.
-//     *
-//     * @param factory the factory to register
-//     * @return an object that can be used to unregister the registered factory.
-//     *
-//     * @stable ICU 2.6
-//     */
-//    public static final Object registerFactory(CollatorFactory factory) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Unregisters a collator previously registered using registerInstance.
-//     * @param registryKey the object previously returned by registerInstance.
-//     * @return true if the collator was successfully unregistered.
-//     * @stable ICU 2.6
-//     */
-//    public static final boolean unregister(Object registryKey) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Returns the set of locales, as Locale objects, for which collators
-     * are installed.  Note that Locale objects do not support RFC 3066.
-     * @return the list of locales in which collators are installed.
-     * This list includes any that have been registered, in addition to
-     * those that are installed with ICU4J.
-     * @stable ICU 2.4
-     */
-    public static Locale[] getAvailableLocales() {
-        return java.text.Collator.getAvailableLocales();
-    }
-
-    /**
-     * {@icu} Returns the set of locales, as ULocale objects, for which collators
-     * are installed.  ULocale objects support RFC 3066.
-     * @return the list of locales in which collators are installed.
-     * This list includes any that have been registered, in addition to
-     * those that are installed with ICU4J.
-     * @stable ICU 3.0
-     */
-    public static final ULocale[] getAvailableULocales() {
-        Locale[] locales = java.text.Collator.getAvailableLocales();
-        ULocale[] ulocales = new ULocale[locales.length];
-        for (int i = 0; i < locales.length; ++i) {
-            ulocales[i] = ULocale.forLocale(locales[i]);
-        }
-        return ulocales;
-    }
-
-    /**
-     * {@icu} Returns an array of all possible keywords that are relevant to
-     * collation. At this point, the only recognized keyword for this
-     * service is "collation".
-     * @return an array of valid collation keywords.
-     * @see #getKeywordValues
-     * @stable ICU 3.0
-     */
-    public static final String[] getKeywords() {
-        // No keywords support in com.ibm.icu.base
-        return new String[0];
-    }
-
-    /**
-     * {@icu} Given a keyword, returns an array of all values for
-     * that keyword that are currently in use.
-     * @param keyword one of the keywords returned by getKeywords.
-     * @see #getKeywords
-     * @stable ICU 3.0
-     */
-    public static final String[] getKeywordValues(String keyword) {
-        // No keywords support in com.ibm.icu.base
-        return new String[0];
-    }
-
-//    /**
-//     * {@icu} Given a key and a locale, returns an array of string values in a preferred
-//     * order that would make a difference. These are all and only those values where
-//     * the open (creation) of the service with the locale formed from the input locale
-//     * plus input keyword and that value has different behavior than creation with the
-//     * input locale alone.
-//     * @param key           one of the keys supported by this service.  For now, only
-//     *                      "collation" is supported.
-//     * @param locale        the locale
-//     * @param commonlyUsed  if set to true it will return only commonly used values
-//     *                      with the given locale in preferred order.  Otherwise,
-//     *                      it will return all the available values for the locale.
-//     * @return an array of string values for the given key and the locale.
-//     * @stable ICU 4.2
-//     */
-//    public static final String[] getKeywordValuesForLocale(String key, ULocale locale, 
-//                                                           boolean commonlyUsed) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the functionally equivalent locale for the given
-//     * requested locale, with respect to given keyword, for the
-//     * collation service.  If two locales return the same result, then
-//     * collators instantiated for these locales will behave
-//     * equivalently.  The converse is not always true; two collators
-//     * may in fact be equivalent, but return different results, due to
-//     * internal details.  The return result has no other meaning than
-//     * that stated above, and implies nothing as to the relationship
-//     * between the two locales.  This is intended for use by
-//     * applications who wish to cache collators, or otherwise reuse
-//     * collators when possible.  The functional equivalent may change
-//     * over time.  For more information, please see the <a
-//     * href="http://www.icu-project.org/userguide/locale.html#services">
-//     * Locales and Services</a> section of the ICU User Guide.
-//     * @param keyword a particular keyword as enumerated by
-//     * getKeywords.
-//     * @param locID The requested locale
-//     * @param isAvailable If non-null, isAvailable[0] will receive and
-//     * output boolean that indicates whether the requested locale was
-//     * 'available' to the collation service. If non-null, isAvailable
-//     * must have length >= 1.
-//     * @return the locale
-//     * @stable ICU 3.0
-//     */
-//    public static final ULocale getFunctionalEquivalent(String keyword,
-//                                                        ULocale locID,
-//                                                        boolean isAvailable[]) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the functionally equivalent locale for the given
-//     * requested locale, with respect to given keyword, for the
-//     * collation service.
-//     * @param keyword a particular keyword as enumerated by
-//     * getKeywords.
-//     * @param locID The requested locale
-//     * @return the locale
-//     * @see #getFunctionalEquivalent(String,ULocale,boolean[])
-//     * @stable ICU 3.0
-//     */
-//    public static final ULocale getFunctionalEquivalent(String keyword,
-//                                                        ULocale locID) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the name of the collator for the objectLocale, localized for the
-//     * displayLocale.
-//     * @param objectLocale the locale of the collator
-//     * @param displayLocale the locale for the collator's display name
-//     * @return the display name
-//     * @stable ICU 2.6
-//     */
-//    static public String getDisplayName(Locale objectLocale, Locale displayLocale) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the name of the collator for the objectLocale, localized for the
-//     * displayLocale.
-//     * @param objectLocale the locale of the collator
-//     * @param displayLocale the locale for the collator's display name
-//     * @return the display name
-//     * @stable ICU 3.2
-//     */
-//    static public String getDisplayName(ULocale objectLocale, ULocale displayLocale) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the name of the collator for the objectLocale, localized for the
-//     * current locale.
-//     * @param objectLocale the locale of the collator
-//     * @return the display name
-//     * @stable ICU 2.6
-//     */
-//    static public String getDisplayName(Locale objectLocale) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the name of the collator for the objectLocale, localized for the
-//     * current locale.
-//     * @param objectLocale the locale of the collator
-//     * @return the display name
-//     * @stable ICU 3.2
-//     */
-//    static public String getDisplayName(ULocale objectLocale) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Returns this Collator's strength property. The strength property
-     * determines the minimum level of difference considered significant.
-     * </p>
-     * {@icunote} This can return QUATERNARY strength, which is not supported by the
-     * JDK version.
-     * <p>
-     * See the Collator class description for more details.
-     * </p>
-     * @return this Collator's current strength property.
-     * @see #setStrength
-     * @see #PRIMARY
-     * @see #SECONDARY
-     * @see #TERTIARY
-     * @see #QUATERNARY
-     * @see #IDENTICAL
-     * @stable ICU 2.8
-     */
-    public int getStrength()
-    {
-        return collator.getStrength();
-    }
-
-    /**
-     * Returns the decomposition mode of this Collator. The decomposition mode
-     * determines how Unicode composed characters are handled.
-     * </p>
-     * <p>
-     * See the Collator class description for more details.
-     * </p>
-     * @return the decomposition mode
-     * @see #setDecomposition
-     * @see #NO_DECOMPOSITION
-     * @see #CANONICAL_DECOMPOSITION
-     * @stable ICU 2.8
-     */
-    public int getDecomposition()
-    {
-        return collator.getDecomposition();
-    }
-
-    // public other methods -------------------------------------------------
-
-    /**
-     * Compares the equality of two text Strings using
-     * this Collator's rules, strength and decomposition mode.  Convenience method.
-     * @param source the source string to be compared.
-     * @param target the target string to be compared.
-     * @return true if the strings are equal according to the collation
-     *         rules, otherwise false.
-     * @see #compare
-     * @throws NullPointerException thrown if either arguments is null.
-     * @stable ICU 2.8
-     */
-    public boolean equals(String source, String target)
-    {
-        return (compare(source, target) == 0);
-    }
-
-//    /**
-//     * {@icu} Returns a UnicodeSet that contains all the characters and sequences tailored
-//     * in this collator.
-//     * @return a pointer to a UnicodeSet object containing all the
-//     *         code points and sequences that may sort differently than
-//     *         in the UCA.
-//     * @stable ICU 2.4
-//     */
-//    public UnicodeSet getTailoredSet()
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Compares the source text String to the target text String according to
-     * this Collator's rules, strength and decomposition mode.
-     * Returns an integer less than,
-     * equal to or greater than zero depending on whether the source String is
-     * less than, equal to or greater than the target String. See the Collator
-     * class description for an example of use.
-     * </p>
-     * @param source the source String.
-     * @param target the target String.
-     * @return Returns an integer value. Value is less than zero if source is
-     *         less than target, value is zero if source and target are equal,
-     *         value is greater than zero if source is greater than target.
-     * @see CollationKey
-     * @see #getCollationKey
-     * @throws NullPointerException thrown if either argument is null.
-     * @stable ICU 2.8
-     */
-    public int compare(String source, String target) {
-        return collator.compare(source, target);
-    }
-
-    /**
-     * Compares the source Object to the target Object.
-     * </p>
-     * @param source the source Object.
-     * @param target the target Object.
-     * @return Returns an integer value. Value is less than zero if source is
-     *         less than target, value is zero if source and target are equal,
-     *         value is greater than zero if source is greater than target.
-     * @throws ClassCastException thrown if either arguments cannot be cast to String.
-     * @stable ICU 4.2
-     */
-    public int compare(Object source, Object target) {
-        return compare((String)source, (String)target);
-    }
-
-    /**
-     * <p>
-     * Transforms the String into a CollationKey suitable for efficient
-     * repeated comparison.  The resulting key depends on the collator's
-     * rules, strength and decomposition mode.
-     * </p>
-     * <p>See the CollationKey class documentation for more information.</p>
-     * @param source the string to be transformed into a CollationKey.
-     * @return the CollationKey for the given String based on this Collator's
-     *         collation rules. If the source String is null, a null
-     *         CollationKey is returned.
-     * @see CollationKey
-     * @see #compare(String, String)
-     * @see #getRawCollationKey
-     * @stable ICU 2.8
-     */
-    public CollationKey getCollationKey(String source) {
-        return new CollationKey(collator.getCollationKey(source));
-    }
-
-//    /**
-//     * {@icu} Returns the simpler form of a CollationKey for the String source following
-//     * the rules of this Collator and stores the result into the user provided argument
-//     * key.  If key has a internal byte array of length that's too small for the result,
-//     * the internal byte array will be grown to the exact required size.
-//     * @param source the text String to be transformed into a RawCollationKey
-//     * @return If key is null, a new instance of RawCollationKey will be
-//     *         created and returned, otherwise the user provided key will be
-//     *         returned.
-//     * @see #compare(String, String)
-//     * @see #getCollationKey
-//     * @see RawCollationKey
-//     * @stable ICU 2.8
-//     */
-//    public RawCollationKey getRawCollationKey(String source, RawCollationKey key) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Variable top is a two byte primary value which causes all the codepoints
-//     * with primary values that are less or equal than the variable top to be
-//     * shifted when alternate handling is set to SHIFTED.
-//     * </p>
-//     * <p>
-//     * Sets the variable top to a collation element value of a string supplied.
-//     * </p>
-//     * @param varTop one or more (if contraction) characters to which the
-//     *               variable top should be set
-//     * @return a int value containing the value of the variable top in upper 16
-//     *         bits. Lower 16 bits are undefined.
-//     * @throws IllegalArgumentException is thrown if varTop argument is not
-//     *            a valid variable top element. A variable top element is
-//     *            invalid when it is a contraction that does not exist in the
-//     *            Collation order or when the PRIMARY strength collation
-//     *            element for the variable top has more than two bytes
-//     * @see #getVariableTop
-//     * @see RuleBasedCollator#setAlternateHandlingShifted
-//     * @stable ICU 2.6
-//     */
-//    public int setVariableTop(String varTop) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the variable top value of a Collator.
-//     * Lower 16 bits are undefined and should be ignored.
-//     * @return the variable top value of a Collator.
-//     * @see #setVariableTop
-//     * @stable ICU 2.6
-//     */
-//    public int getVariableTop() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the variable top to a collation element value supplied.
-//     * Variable top is set to the upper 16 bits.
-//     * Lower 16 bits are ignored.
-//     * @param varTop Collation element value, as returned by setVariableTop or
-//     *               getVariableTop
-//     * @see #getVariableTop
-//     * @see #setVariableTop
-//     * @stable ICU 2.6
-//     */
-//    public void setVariableTop(int varTop) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the version of this collator object.
-//     * @return the version object associated with this collator
-//     * @stable ICU 2.8
-//     */
-//    public VersionInfo getVersion() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the UCA version of this collator object.
-//     * @return the version object associated with this collator
-//     * @stable ICU 2.8
-//     */
-//    public VersionInfo getUCAVersion() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**  
-//     * Retrieves the reordering codes for this collator.
-//     * These reordering codes are a combination of UScript codes and ReorderCodes.
-//     * @return a copy of the reordering codes for this collator; 
-//     * if none are set then returns an empty array
-//     * @see #setReorderCodes
-//     * @see #getEquivalentReorderCodes
-//     * @draft ICU 4.8
-//     */ 
-//    public int[] getReorderCodes() 
-//    { 
-//        throw new UnsupportedOperationException(); 
-//    }   
-
-//    /** 
-//     * Sets the reordering codes for this collator.
-//     * Reordering codes allow the collation ordering for groups of characters to be changed.
-//     * The reordering codes are a combination of UScript  codes and ReorderCodes.
-//     * These allow the ordering of characters belonging to these groups to be changed as a group.  
-//     * @param order the reordering codes to apply to this collator; if this is null or an empty array
-//     * then this clears any existing reordering
-//     * @see #getReorderCodes
-//     * @see #getEquivalentReorderCodes
-//     * @draft ICU 4.8
-//     */ 
-//    public void setReorderCodes(int... order) 
-//    { 
-//        throw new UnsupportedOperationException(); 
-//    } 
-
-//    /**
-//     * Retrieves all the reorder codes that are grouped with the given reorder code. Some reorder
-//     * codes are grouped and must reorder together.
-//     * 
-//     * @param reorderCode code for which equivalents to be retrieved
-//     * @return the set of all reorder codes in the same group as the given reorder code.
-//     * @see #setReorderCodes
-//     * @see #getReorderCodes
-//     * @draft ICU 4.8
-//     */
-//    public static int[] getEquivalentReorderCodes(int reorderCode)
-//    { 
-//        throw new UnsupportedOperationException(); 
-//    }
-
-//    /**
-//     * {@icu} Returns the locale that was used to create this object, or null.
-//     * This may may differ from the locale requested at the time of
-//     * this object's creation.  For example, if an object is created
-//     * for locale <tt>en_US_CALIFORNIA</tt>, the actual data may be
-//     * drawn from <tt>en</tt> (the <i>actual</i> locale), and
-//     * <tt>en_US</tt> may be the most specific locale that exists (the
-//     * <i>valid</i> locale).
-//     *
-//     * <p>Note: This method will be implemented in ICU 3.0; ICU 2.8
-//     * contains a partial preview implementation.  The * <i>actual</i>
-//     * locale is returned correctly, but the <i>valid</i> locale is
-//     * not, in most cases.
-//     * @param type type of information requested, either {@link
-//     * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link
-//     * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}.
-//     * @return the information specified by <i>type</i>, or null if
-//     * this object was not constructed from locale data.
-//     * @see com.ibm.icu.util.ULocale
-//     * @see com.ibm.icu.util.ULocale#VALID_LOCALE
-//     * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
-//     * @draft ICU 2.8 (retain)
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public final ULocale getLocale(ULocale.Type type) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    // com.ibm.icu.base specific overrides
-    public String toString() {
-        return collator.toString();
-    }
-
-    public boolean equals(Object rhs) {
-        try {
-            return collator.equals(((Collator)rhs).collator);
-        }
-        catch (Exception e) {
-            return false;
-        }
-    }
-
-    public int hashCode() {
-        return collator.hashCode();
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormat.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormat.java
deleted file mode 100644
index 1958b68..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormat.java
+++ /dev/null
@@ -1,2091 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *   Copyright (C) 1996-2012, International Business Machines
- *   Corporation and others.  All Rights Reserved.
- */
-
-package com.ibm.icu.text;
-
-import java.io.InvalidObjectException;
-import java.text.FieldPosition;
-import java.text.Format;
-import java.text.ParseException;
-import java.text.ParsePosition;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
-import com.ibm.icu.util.Calendar;
-import com.ibm.icu.util.TimeZone;
-import com.ibm.icu.util.ULocale;
-import com.ibm.icu.util.ULocale.Category;
-
-/**
- * {@icuenhanced java.text.DateFormat}.{@icu _usage_}
- *
- * <p>DateFormat is an abstract class for date/time formatting subclasses which
- * formats and parses dates or time in a language-independent manner.
- * The date/time formatting subclass, such as SimpleDateFormat, allows for
- * formatting (i.e., date -> text), parsing (text -> date), and
- * normalization.  The date is represented as a <code>Date</code> object or
- * as the milliseconds since January 1, 1970, 00:00:00 GMT.
- *
- * <p>DateFormat provides many class methods for obtaining default date/time
- * formatters based on the default or a given locale and a number of formatting
- * styles. The formatting styles include FULL, LONG, MEDIUM, and SHORT. More
- * detail and examples of using these styles are provided in the method
- * descriptions.
- *
- * <p>DateFormat helps you to format and parse dates for any locale.
- * Your code can be completely independent of the locale conventions for
- * months, days of the week, or even the calendar format: lunar vs. solar.
- *
- * <p>To format a date for the current Locale, use one of the
- * static factory methods:
- * <pre>
- *  myString = DateFormat.getDateInstance().format(myDate);
- * </pre>
- * <p>If you are formatting multiple numbers, it is
- * more efficient to get the format and use it multiple times so that
- * the system doesn't have to fetch the information about the local
- * language and country conventions multiple times.
- * <pre>
- *  DateFormat df = DateFormat.getDateInstance();
- *  for (int i = 0; i < a.length; ++i) {
- *    output.println(df.format(myDate[i]) + "; ");
- *  }
- * </pre>
- * <p>To format a number for a different Locale, specify it in the
- * call to getDateInstance().
- * <pre>
- *  DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);
- * </pre>
- * <p>You can use a DateFormat to parse also.
- * <pre>
- *  myDate = df.parse(myString);
- * </pre>
- * <p>Use getDateInstance to get the normal date format for that country.
- * There are other static factory methods available.
- * Use getTimeInstance to get the time format for that country.
- * Use getDateTimeInstance to get a date and time format. You can pass in
- * different options to these factory methods to control the length of the
- * result; from SHORT to MEDIUM to LONG to FULL. The exact result depends
- * on the locale, but generally:
- * <ul><li>SHORT is completely numeric, such as 12.13.52 or 3:30pm
- * <li>MEDIUM is longer, such as Jan 12, 1952
- * <li>LONG is longer, such as January 12, 1952 or 3:30:32pm
- * <li>FULL is pretty completely specified, such as
- * Tuesday, April 12, 1952 AD or 3:30:42pm PST.
- * </ul>
- *
- * <p>You can also set the time zone on the format if you wish.
- * If you want even more control over the format or parsing,
- * (or want to give your users more control),
- * you can try casting the DateFormat you get from the factory methods
- * to a SimpleDateFormat. This will work for the majority
- * of countries; just remember to put it in a try block in case you
- * encounter an unusual one.
- *
- * <p>You can also use forms of the parse and format methods with
- * ParsePosition and FieldPosition to
- * allow you to
- * <ul><li>progressively parse through pieces of a string.
- * <li>align any particular field, or find out where it is for selection
- * on the screen.
- * </ul>
- *
- * <h4>Synchronization</h4>
- *
- * Date formats are not synchronized. It is recommended to create separate
- * format instances for each thread. If multiple threads access a format
- * concurrently, it must be synchronized externally.
- *
- * @see          UFormat
- * @see          NumberFormat
- * @see          SimpleDateFormat
- * @see          com.ibm.icu.util.Calendar
- * @see          com.ibm.icu.util.GregorianCalendar
- * @see          com.ibm.icu.util.TimeZone
- * @author       Mark Davis, Chen-Lieh Huang, Alan Liu
- * @stable ICU 2.0
- */
-public class DateFormat extends Format {
-
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * @internal
-     */
-    public final java.text.DateFormat dateFormat;
-        
-    /**
-     * @internal
-     * @param delegate the DateFormat to which to delegate
-     */
-    public DateFormat(java.text.DateFormat delegate) {
-        this.dateFormat = delegate;
-    }
-    
-    /**
-     * For subclass use.  Subclasses will generally not
-     * work correctly unless they manipulate the delegate.
-     */
-    protected DateFormat() {
-        this.dateFormat = java.text.DateFormat.getDateTimeInstance(
-                java.text.DateFormat.SHORT,
-                java.text.DateFormat.SHORT,
-                ULocale.getDefault(Category.FORMAT).toLocale());
-    }
-
-    /**
-     * FieldPosition selector for 'G' field alignment,
-     * corresponding to the {@link Calendar#ERA} field.
-     * @stable ICU 2.0
-     */
-    public final static int ERA_FIELD = 0;
-
-    /**
-     * FieldPosition selector for 'y' field alignment,
-     * corresponding to the {@link Calendar#YEAR} field.
-     * @stable ICU 2.0
-     */
-    public final static int YEAR_FIELD = 1;
-
-    /**
-     * FieldPosition selector for 'M' field alignment,
-     * corresponding to the {@link Calendar#MONTH} field.
-     * @stable ICU 2.0
-     */
-    public final static int MONTH_FIELD = 2;
-
-    /**
-     * FieldPosition selector for 'd' field alignment,
-     * corresponding to the {@link Calendar#DATE} field.
-     * @stable ICU 2.0
-     */
-    public final static int DATE_FIELD = 3;
-
-    /**
-     * FieldPosition selector for 'k' field alignment,
-     * corresponding to the {@link Calendar#HOUR_OF_DAY} field.
-     * HOUR_OF_DAY1_FIELD is used for the one-based 24-hour clock.
-     * For example, 23:59 + 01:00 results in 24:59.
-     * @stable ICU 2.0
-     */
-    public final static int HOUR_OF_DAY1_FIELD = 4;
-
-    /**
-     * FieldPosition selector for 'H' field alignment,
-     * corresponding to the {@link Calendar#HOUR_OF_DAY} field.
-     * HOUR_OF_DAY0_FIELD is used for the zero-based 24-hour clock.
-     * For example, 23:59 + 01:00 results in 00:59.
-     * @stable ICU 2.0
-     */
-    public final static int HOUR_OF_DAY0_FIELD = 5;
-
-    /**
-     * FieldPosition selector for 'm' field alignment,
-     * corresponding to the {@link Calendar#MINUTE} field.
-     * @stable ICU 2.0
-     */
-    public final static int MINUTE_FIELD = 6;
-
-    /**
-     * FieldPosition selector for 's' field alignment,
-     * corresponding to the {@link Calendar#SECOND} field.
-     * @stable ICU 2.0
-     */
-    public final static int SECOND_FIELD = 7;
-
-    /**
-     * {@icu} FieldPosition selector for 'S' field alignment,
-     * corresponding to the {@link Calendar#MILLISECOND} field.
-     * @stable ICU 3.0
-     */
-    public final static int FRACTIONAL_SECOND_FIELD = 8;
-
-    /**
-     * Alias for FRACTIONAL_SECOND_FIELD.
-     * @stable ICU 3.0 FRACTIONAL_SECOND_FIELD.
-     */
-    public final static int MILLISECOND_FIELD = FRACTIONAL_SECOND_FIELD;
-
-    /**
-     * FieldPosition selector for 'E' field alignment,
-     * corresponding to the {@link Calendar#DAY_OF_WEEK} field.
-     * @stable ICU 2.0
-     */
-    public final static int DAY_OF_WEEK_FIELD = 9;
-
-    /**
-     * FieldPosition selector for 'D' field alignment,
-     * corresponding to the {@link Calendar#DAY_OF_YEAR} field.
-     * @stable ICU 2.0
-     */
-    public final static int DAY_OF_YEAR_FIELD = 10;
-
-    /**
-     * FieldPosition selector for 'F' field alignment,
-     * corresponding to the {@link Calendar#DAY_OF_WEEK_IN_MONTH} field.
-     * @stable ICU 2.0
-     */
-    public final static int DAY_OF_WEEK_IN_MONTH_FIELD = 11;
-
-    /**
-     * FieldPosition selector for 'w' field alignment,
-     * corresponding to the {@link Calendar#WEEK_OF_YEAR} field.
-     * @stable ICU 2.0
-     */
-    public final static int WEEK_OF_YEAR_FIELD = 12;
-
-    /**
-     * FieldPosition selector for 'W' field alignment,
-     * corresponding to the {@link Calendar#WEEK_OF_MONTH} field.
-     * @stable ICU 2.0
-     */
-    public final static int WEEK_OF_MONTH_FIELD = 13;
-
-    /**
-     * FieldPosition selector for 'a' field alignment,
-     * corresponding to the {@link Calendar#AM_PM} field.
-     * @stable ICU 2.0
-     */
-    public final static int AM_PM_FIELD = 14;
-
-    /**
-     * FieldPosition selector for 'h' field alignment,
-     * corresponding to the {@link Calendar#HOUR} field.
-     * HOUR1_FIELD is used for the one-based 12-hour clock.
-     * For example, 11:30 PM + 1 hour results in 12:30 AM.
-     * @stable ICU 2.0
-     */
-    public final static int HOUR1_FIELD = 15;
-
-    /**
-     * FieldPosition selector for 'K' field alignment,
-     * corresponding to the {@link Calendar#HOUR} field.
-     * HOUR0_FIELD is used for the zero-based 12-hour clock.
-     * For example, 11:30 PM + 1 hour results in 00:30 AM.
-     * @stable ICU 2.0
-     */
-    public final static int HOUR0_FIELD = 16;
-
-    /**
-     * FieldPosition selector for 'z' field alignment,
-     * corresponding to the {@link Calendar#ZONE_OFFSET} and
-     * {@link Calendar#DST_OFFSET} fields.
-     * @stable ICU 2.0
-     */
-    public final static int TIMEZONE_FIELD = 17;
-
-    /**
-     * {@icu} FieldPosition selector for 'Y' field alignment,
-     * corresponding to the {@link Calendar#YEAR_WOY} field.
-     * @stable ICU 3.0
-     */
-    public final static int YEAR_WOY_FIELD = 18;
-
-    /**
-     * {@icu} FieldPosition selector for 'e' field alignment,
-     * corresponding to the {@link Calendar#DOW_LOCAL} field.
-     * @stable ICU 3.0
-     */
-    public final static int DOW_LOCAL_FIELD = 19;
-
-    /**
-     * {@icu} FieldPosition selector for 'u' field alignment,
-     * corresponding to the {@link Calendar#EXTENDED_YEAR} field.
-     * @stable ICU 3.0
-     */
-    public final static int EXTENDED_YEAR_FIELD = 20;
-
-    /**
-     * {@icu} FieldPosition selector for 'g' field alignment,
-     * corresponding to the {@link Calendar#JULIAN_DAY} field.
-     * @stable ICU 3.0
-     */
-    public final static int JULIAN_DAY_FIELD = 21;
-
-    /**
-     * {@icu} FieldPosition selector for 'A' field alignment,
-     * corresponding to the {@link Calendar#MILLISECONDS_IN_DAY} field.
-     * @stable ICU 3.0
-     */
-    public final static int MILLISECONDS_IN_DAY_FIELD = 22;
-
-    /**
-     * {@icu} FieldPosition selector for 'Z' field alignment,
-     * corresponding to the {@link Calendar#ZONE_OFFSET} and
-     * {@link Calendar#DST_OFFSET} fields.
-     * @stable ICU 3.0
-     */
-    public final static int TIMEZONE_RFC_FIELD = 23;
-
-    /**
-     * {@icu} FieldPosition selector for 'v' field alignment,
-     * corresponding to the {@link Calendar#ZONE_OFFSET} and
-     * {@link Calendar#DST_OFFSET} fields.  This displays the generic zone
-     * name, if available.
-     * @stable ICU 3.4
-     */
-    public final static int TIMEZONE_GENERIC_FIELD = 24;
-
-    /**
-     * {@icu} FieldPosition selector for 'c' field alignment,
-     * corresponding to the {@link Calendar#DAY_OF_WEEK} field.
-     * This displays the stand alone day name, if available.
-     * @stable ICU 3.4
-     */
-    public final static int STANDALONE_DAY_FIELD = 25;
-
-    /**
-     * {@icu} FieldPosition selector for 'L' field alignment,
-     * corresponding to the {@link Calendar#MONTH} field.
-     * This displays the stand alone month name, if available.
-     * @stable ICU 3.4
-     */
-    public final static int STANDALONE_MONTH_FIELD = 26;
-
-    /**
-     * {@icu} FieldPosition selector for 'Q' field alignment,
-     * corresponding to the {@link Calendar#MONTH} field.
-     * This displays the quarter.
-     * @stable ICU 3.6
-     */
-    public final static int QUARTER_FIELD = 27;
-
-    /**
-     * {@icu} FieldPosition selector for 'q' field alignment,
-     * corresponding to the {@link Calendar#MONTH} field.
-     * This displays the stand alone quarter, if available.
-     * @stable ICU 3.6
-     */
-    public final static int STANDALONE_QUARTER_FIELD = 28;
-
-    /**
-     * {@icu} FieldPosition selector for 'V' field alignment,
-     * corresponding to the {@link Calendar#ZONE_OFFSET} and
-     * {@link Calendar#DST_OFFSET} fields.  This displays the fallback timezone
-     * name when VVVV is specified, and the short standard or daylight
-     * timezone name ignoring commonlyUsed when a single V is specified.
-     * @stable ICU 3.8
-     */
-    public final static int TIMEZONE_SPECIAL_FIELD = 29;
-
-    /**
-     * {@icu} Number of FieldPosition selectors for DateFormat.
-     * Valid selectors range from 0 to FIELD_COUNT-1.
-     * @stable ICU 3.0
-     */
-    public final static int FIELD_COUNT = 30; // must == DateFormatSymbols.patternChars.length()
-
-    /**
-     * Formats a time object into a time string. Examples of time objects
-     * are a time value expressed in milliseconds and a Date object.
-     * @param obj must be a Number or a Date or a Calendar.
-     * @param toAppendTo the string buffer for the returning time string.
-     * @return the formatted time string.
-     * @param fieldPosition keeps track of the position of the field
-     * within the returned string.
-     * On input: an alignment field,
-     * if desired. On output: the offsets of the alignment field. For
-     * example, given a time text "1996.07.10 AD at 15:08:56 PDT",
-     * if the given fieldPosition is DateFormat.YEAR_FIELD, the
-     * begin index and end index of fieldPosition will be set to
-     * 0 and 4, respectively.
-     * Notice that if the same time field appears
-     * more than once in a pattern, the fieldPosition will be set for the first
-     * occurrence of that time field. For instance, formatting a Date to
-     * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern
-     * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD,
-     * the begin index and end index of fieldPosition will be set to
-     * 5 and 8, respectively, for the first occurrence of the timezone
-     * pattern character 'z'.
-     * @see java.text.Format
-     * @stable ICU 2.0
-     */
-    public final StringBuffer format(Object obj, StringBuffer toAppendTo,
-                                     FieldPosition fieldPosition)
-    {
-        if (obj instanceof Calendar) {
-            return format((Calendar)obj, toAppendTo, fieldPosition);
-        } else if (obj instanceof Date) {
-            return format((Date)obj, toAppendTo, fieldPosition);
-        } else if (obj instanceof Number) {
-            return format(new Date(((Number)obj).longValue()), toAppendTo, fieldPosition );
-        }
-
-        throw new IllegalArgumentException("Cannot format given Object (" +
-                                               obj.getClass().getName() + ") as a Date");
-    }
-
-    /**
-     * Formats a date into a date/time string.
-     * @param cal a Calendar set to the date and time to be formatted
-     * into a date/time string.  When the calendar type is different from
-     * the internal calendar held by this DateFormat instance, the date
-     * and the time zone will be inherited from the input calendar, but
-     * other calendar field values will be calculated by the internal calendar.
-     * @param toAppendTo the string buffer for the returning date/time string.
-     * @param fieldPosition keeps track of the position of the field
-     * within the returned string.
-     * On input: an alignment field,
-     * if desired. On output: the offsets of the alignment field. For
-     * example, given a time text "1996.07.10 AD at 15:08:56 PDT",
-     * if the given fieldPosition is DateFormat.YEAR_FIELD, the
-     * begin index and end index of fieldPosition will be set to
-     * 0 and 4, respectively.
-     * Notice that if the same time field appears
-     * more than once in a pattern, the fieldPosition will be set for the first
-     * occurrence of that time field. For instance, formatting a Date to
-     * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern
-     * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD,
-     * the begin index and end index of fieldPosition will be set to
-     * 5 and 8, respectively, for the first occurrence of the timezone
-     * pattern character 'z'.
-     * @return the formatted date/time string.
-     * @stable ICU 2.0
-     */
-    public StringBuffer format(Calendar cal, StringBuffer toAppendTo,
-                                        FieldPosition fieldPosition) {
-        return format(cal.getTime(), toAppendTo, fieldPosition);
-    }
-
-    /**
-     * Formats a Date into a date/time string.
-     * @param date a Date to be formatted into a date/time string.
-     * @param toAppendTo the string buffer for the returning date/time string.
-     * @param fieldPosition keeps track of the position of the field
-     * within the returned string.
-     * On input: an alignment field,
-     * if desired. On output: the offsets of the alignment field. For
-     * example, given a time text "1996.07.10 AD at 15:08:56 PDT",
-     * if the given fieldPosition is DateFormat.YEAR_FIELD, the
-     * begin index and end index of fieldPosition will be set to
-     * 0 and 4, respectively.
-     * Notice that if the same time field appears
-     * more than once in a pattern, the fieldPosition will be set for the first
-     * occurrence of that time field. For instance, formatting a Date to
-     * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern
-     * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD,
-     * the begin index and end index of fieldPosition will be set to
-     * 5 and 8, respectively, for the first occurrence of the timezone
-     * pattern character 'z'.
-     * @return the formatted date/time string.
-     * @stable ICU 2.0
-     */
-    public StringBuffer format(Date date, StringBuffer toAppendTo,
-                                     FieldPosition fieldPosition) {
-        FieldPosition jdkPos = toJDKFieldPosition(fieldPosition);
-        StringBuffer buf = dateFormat.format(date, toAppendTo, jdkPos);
-        if (jdkPos != null) {
-            fieldPosition.setBeginIndex(jdkPos.getBeginIndex());
-            fieldPosition.setEndIndex(jdkPos.getEndIndex());
-        }
-        return buf;
-    }
-
-    /**
-     * Formats a Date into a date/time string.
-     * @param date the time value to be formatted into a time string.
-     * @return the formatted time string.
-     * @stable ICU 2.0
-     */
-    public final String format(Date date)
-    {
-        return dateFormat.format(date);
-    }
-
-    /**
-     * Parses a date/time string.
-     *
-     * @param text  The date/time string to be parsed
-     *
-     * @return      A Date, or null if the input could not be parsed
-     *
-     * @exception  ParseException  If the given string cannot be parsed as a date.
-     *
-     * @see #parse(String, ParsePosition)
-     * @stable ICU 2.0
-     */
-    public Date parse(String text) throws ParseException
-    {
-        return dateFormat.parse(text);
-    }
-
-    /**
-     * Parses a date/time string according to the given parse position.
-     * For example, a time text "07/10/96 4:5 PM, PDT" will be parsed
-     * into a Calendar that is equivalent to Date(837039928046).  The
-     * caller should clear the calendar before calling this method,
-     * unless existing field information is to be kept.
-     *
-     * <p> By default, parsing is lenient: If the input is not in the form used
-     * by this object's format method but can still be parsed as a date, then
-     * the parse succeeds.  Clients may insist on strict adherence to the
-     * format by calling setLenient(false).
-     *
-     * @see #setLenient(boolean)
-     *
-     * @param text  The date/time string to be parsed
-     *
-     * @param cal   The calendar into which parsed data will be stored.
-     *              In general, this should be cleared before calling this
-     *              method.  If this parse fails, the calendar may still
-     *              have been modified.  When the calendar type is different
-     *              from the internal calendar held by this DateFormat
-     *              instance, calendar field values will be parsed based
-     *              on the internal calendar initialized with the time and
-     *              the time zone taken from this calendar, then the
-     *              parse result (time in milliseconds and time zone) will
-     *              be set back to this calendar.
-     *
-     * @param pos   On input, the position at which to start parsing; on
-     *              output, the position at which parsing terminated, or the
-     *              start position if the parse failed.
-     * @stable ICU 2.0
-     */
-    public void parse(String text, Calendar cal, ParsePosition pos) {
-        Date result = dateFormat.parse(text, pos);
-        cal.setTime(result);
-    }
-
-    /**
-     * Parses a date/time string according to the given parse position.  For
-     * example, a time text "07/10/96 4:5 PM, PDT" will be parsed into a Date
-     * that is equivalent to Date(837039928046).
-     *
-     * <p> By default, parsing is lenient: If the input is not in the form used
-     * by this object's format method but can still be parsed as a date, then
-     * the parse succeeds.  Clients may insist on strict adherence to the
-     * format by calling setLenient(false).
-     *
-     * @see #setLenient(boolean)
-     *
-     * @param text  The date/time string to be parsed
-     *
-     * @param pos   On input, the position at which to start parsing; on
-     *              output, the position at which parsing terminated, or the
-     *              start position if the parse failed.
-     *
-     * @return      A Date, or null if the input could not be parsed
-     * @stable ICU 2.0
-     */
-    public Date parse(String text, ParsePosition pos) {
-        return dateFormat.parse(text, pos);
-    }
-
-    /**
-     * Parses a date/time string into an Object.  This convenience method simply
-     * calls parse(String, ParsePosition).
-     *
-     * @see #parse(String, ParsePosition)
-     * @stable ICU 2.0
-     */
-    public Object parseObject (String source, ParsePosition pos)
-    {
-        return parse(source, pos);
-    }
-
-    /**
-     * {@icu} Constant for empty style pattern.
-     * @stable ICU 3.8
-     */
-    public static final int NONE = -1;
-
-    /**
-     * Constant for full style pattern.
-     * @stable ICU 2.0
-     */
-    public static final int FULL = 0;
-
-    /**
-     * Constant for long style pattern.
-     * @stable ICU 2.0
-     */
-    public static final int LONG = 1;
-
-    /**
-     * Constant for medium style pattern.
-     * @stable ICU 2.0
-     */
-    public static final int MEDIUM = 2;
-
-    /**
-     * Constant for short style pattern.
-     * @stable ICU 2.0
-     */
-    public static final int SHORT = 3;
-
-    /**
-     * Constant for default style pattern.  Its value is MEDIUM.
-     * @stable ICU 2.0
-     */
-    public static final int DEFAULT = MEDIUM;
-
-    /**
-     * {@icu} Constant for relative style mask.
-     * @stable ICU 3.8
-     */
-    public static final int RELATIVE = (1 << 7);
-
-    /**
-     * {@icu} Constant for relative full style pattern.
-     * @stable ICU 3.8
-     */
-    public static final int RELATIVE_FULL = RELATIVE | FULL;
-
-    /**
-     * {@icu} Constant for relative style pattern.
-     * @stable ICU 3.8
-     */
-    public static final int RELATIVE_LONG = RELATIVE | LONG;
-
-    /**
-     * {@icu} Constant for relative style pattern.
-     * @stable ICU 3.8
-     */
-    public static final int RELATIVE_MEDIUM = RELATIVE | MEDIUM;
-
-    /**
-     * {@icu} Constant for relative style pattern.
-     * @stable ICU 3.8
-     */
-    public static final int RELATIVE_SHORT = RELATIVE | SHORT;
-
-    /**
-     * {@icu} Constant for relative default style pattern.
-     * @stable ICU 3.8
-     */
-    public static final int RELATIVE_DEFAULT = RELATIVE | DEFAULT;
-
-    /*
-     * DATES
-     */
-
-    /**
-     * {@icu} Constant for date skeleton with year.
-     * @stable ICU 4.0
-     */
-    public static final String YEAR = "y";
-
-    /**
-     * {@icu} Constant for date skeleton with quarter.
-     * @draft ICU 50
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final String QUARTER = "QQQQ";
-
-    /**
-     * {@icu} Constant for date skeleton with abbreviated quarter.
-     * @draft ICU 50
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final String ABBR_QUARTER = "QQQ";
-
-    /**
-     * {@icu} Constant for date skeleton with year and quarter.
-     * @stable ICU 4.0
-     */
-    public static final String YEAR_QUARTER = "yQQQQ";
-
-    /**
-     * {@icu} Constant for date skeleton with year and abbreviated quarter.
-     * @stable ICU 4.0
-     */
-    public static final String YEAR_ABBR_QUARTER = "yQQQ";
-
-    /**
-     * {@icu} Constant for date skeleton with month.
-     * @stable ICU 4.0
-     */
-    public static final String MONTH = "MMMM";
-
-    /**
-     * {@icu} Constant for date skeleton with abbreviated month.
-     * @stable ICU 4.0
-     */
-    public static final String ABBR_MONTH = "MMM";
-
-    /**
-     * {@icu} Constant for date skeleton with numeric month.
-     * @stable ICU 4.0
-     */
-    public static final String NUM_MONTH = "M";
-
-    /**
-     * {@icu} Constant for date skeleton with year and month.
-     * @stable ICU 4.0
-     */
-    public static final String YEAR_MONTH = "yMMMM";
-
-    /**
-     * {@icu} Constant for date skeleton with year and abbreviated month.
-     * @stable ICU 4.0
-     */
-    public static final String YEAR_ABBR_MONTH = "yMMM";
-
-    /**
-     * {@icu} Constant for date skeleton with year and numeric month.
-     * @stable ICU 4.0
-     */
-    public static final String YEAR_NUM_MONTH = "yM";
-
-    /**
-     * {@icu} Constant for date skeleton with day.
-     * @stable ICU 4.0
-     */
-    public static final String DAY = "d";
-
-    /**
-     * {@icu} Constant for date skeleton with year, month, and day.
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String YEAR_MONTH_DAY = "yMMMMd";
-
-    /**
-     * {@icu} Constant for date skeleton with year, abbreviated month, and day.
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String YEAR_ABBR_MONTH_DAY = "yMMMd";
-
-    /**
-     * {@icu} Constant for date skeleton with year, numeric month, and day.
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String YEAR_NUM_MONTH_DAY = "yMd";
-
-    /**
-     * {@icu} Constant for date skeleton with weekday.
-     * @draft ICU 50
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final String WEEKDAY = "EEEE";
-
-    /**
-     * {@icu} Constant for date skeleton with abbreviated weekday.
-     * @draft ICU 50
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final String ABBR_WEEKDAY = "E";
-
-    /**
-     * {@icu} Constant for date skeleton with year, month, weekday, and day.
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String YEAR_MONTH_WEEKDAY_DAY = "yMMMMEEEEd";
-
-    /**
-     * {@icu} Constant for date skeleton with year, abbreviated month, weekday, and day.
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String YEAR_ABBR_MONTH_WEEKDAY_DAY = "yMMMEd";
-
-    /**
-     * {@icu} Constant for date skeleton with year, numeric month, weekday, and day.
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String YEAR_NUM_MONTH_WEEKDAY_DAY = "yMEd";
-
-    /**
-     * {@icu} Constant for date skeleton with long month and day.
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String MONTH_DAY = "MMMMd";
-
-    /**
-     * {@icu} Constant for date skeleton with abbreviated month and day.
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String ABBR_MONTH_DAY = "MMMd";
-
-    /**
-     * {@icu} Constant for date skeleton with numeric month and day.
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String NUM_MONTH_DAY = "Md";
-
-    /**
-     * {@icu} Constant for date skeleton with month, weekday, and day.
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String MONTH_WEEKDAY_DAY = "MMMMEEEEd";
-
-    /**
-     * {@icu} Constant for date skeleton with abbreviated month, weekday, and day.
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String ABBR_MONTH_WEEKDAY_DAY = "MMMEd";
-
-    /**
-     * {@icu} Constant for date skeleton with numeric month, weekday, and day.
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String NUM_MONTH_WEEKDAY_DAY = "MEd";
-
-    /*
-     * TIMES
-     */
-
-    /**
-     * {@icu} Constant for date skeleton with hour, with the locale's preferred hour format (12 or 24).
-     * @stable ICU 4.0
-     */
-    public static final String HOUR = "j";
-
-    /**
-     * {@icu} Constant for date skeleton with hour in 24-hour presentation.
-     * @draft ICU 50
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final String HOUR24 = "H";
-
-    /**
-     * {@icu} Constant for date skeleton with minute.
-     * @draft ICU 50
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final String MINUTE = "m";
-
-    /**
-     * {@icu} Constant for date skeleton with hour and minute, with the locale's preferred hour format (12 or 24).
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String HOUR_MINUTE = "jm";
-
-    /**
-     * {@icu} Constant for date skeleton with hour and minute in 24-hour presentation.
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String HOUR24_MINUTE = "Hm";
-
-    /**
-     * {@icu} Constant for date skeleton with second.
-     * @draft ICU 50
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final String SECOND = "s";
-
-    /**
-     * {@icu} Constant for date skeleton with hour, minute, and second,
-     * with the locale's preferred hour format (12 or 24).
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String HOUR_MINUTE_SECOND = "jms";
-
-    /**
-     * {@icu} Constant for date skeleton with hour, minute, and second in
-     * 24-hour presentation.
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String HOUR24_MINUTE_SECOND = "Hms";
-
-    /**
-     * {@icu} Constant for date skeleton with minute and second.
-     * Used in combinations date + time, date + time + zone, or time + zone.
-     * @stable ICU 4.0
-     */
-    public static final String MINUTE_SECOND = "ms";
-
-    /*
-     * TIMEZONES
-     */
-
-    /**
-     * {@icu} Constant for <i>generic location format</i>, such as Los Angeles Time;
-     * used in combinations date + time + zone, or time + zone.
-     * @see <a href="http://unicode.org/reports/tr35/#Date_Format_Patterns">LDML Date Format Patterns</a>
-     * @see <a href="http://unicode.org/reports/tr35/#Time_Zone_Fallback">LDML Time Zone Fallback</a>
-     * @draft ICU 50
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final String LOCATION_TZ = "VVVV";
-    
-    /**
-     * {@icu} Constant for <i>generic non-location format</i>, such as Pacific Time;
-     * used in combinations date + time + zone, or time + zone.
-     * @see <a href="http://unicode.org/reports/tr35/#Date_Format_Patterns">LDML Date Format Patterns</a>
-     * @see <a href="http://unicode.org/reports/tr35/#Time_Zone_Fallback">LDML Time Zone Fallback</a>
-     * @draft ICU 50
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final String GENERIC_TZ = "vvvv";
-    
-    /**
-     * {@icu} Constant for <i>generic non-location format</i>, abbreviated if possible, such as PT;
-     * used in combinations date + time + zone, or time + zone.
-     * @see <a href="http://unicode.org/reports/tr35/#Date_Format_Patterns">LDML Date Format Patterns</a>
-     * @see <a href="http://unicode.org/reports/tr35/#Time_Zone_Fallback">LDML Time Zone Fallback</a>
-     * @draft ICU 50
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final String ABBR_GENERIC_TZ = "v";
-    
-    /**
-     * {@icu} Constant for <i>specific non-location format</i>, such as Pacific Daylight Time;
-     * used in combinations date + time + zone, or time + zone.
-     * @see <a href="http://unicode.org/reports/tr35/#Date_Format_Patterns">LDML Date Format Patterns</a>
-     * @see <a href="http://unicode.org/reports/tr35/#Time_Zone_Fallback">LDML Time Zone Fallback</a>
-     * @draft ICU 50
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final String SPECIFIC_TZ = "zzzz";
-    
-    /**
-     * {@icu} Constant for <i>specific non-location format</i>, abbreviated if possible, such as PDT;
-     * used in combinations date + time + zone, or time + zone.
-     * @see <a href="http://unicode.org/reports/tr35/#Date_Format_Patterns">LDML Date Format Patterns</a>
-     * @see <a href="http://unicode.org/reports/tr35/#Time_Zone_Fallback">LDML Time Zone Fallback</a>
-     * @draft ICU 50
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final String ABBR_SPECIFIC_TZ = "z";
-    
-    /**
-     * {@icu} Constant for <i>localized GMT/UTC format</i>, such as GMT+8:00 or HPG-8:00;
-     * used in combinations date + time + zone, or time + zone.
-     * @see <a href="http://unicode.org/reports/tr35/#Date_Format_Patterns">LDML Date Format Patterns</a>
-     * @see <a href="http://unicode.org/reports/tr35/#Time_Zone_Fallback">LDML Time Zone Fallback</a>
-     * @draft ICU 50
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final String ABBR_UTC_TZ = "ZZZZ";
-
-    /*
-     * deprecated skeleton constants
-     */
-
-    /**
-     * {@icu} Constant for date skeleton with standalone month.
-     * @deprecated ICU 50 Use {@link #MONTH} instead.
-     */
-    public static final String STANDALONE_MONTH = "LLLL";
-
-    /**
-     * {@icu} Constant for date skeleton with standalone abbreviated month.
-     * @deprecated ICU 50 Use {@link #ABBR_MONTH} instead.
-     */
-    public static final String ABBR_STANDALONE_MONTH = "LLL";
-
-    /**
-     * {@icu} Constant for date skeleton with hour, minute, and generic timezone.
-     * @deprecated ICU 50 Use instead {@link #HOUR_MINUTE}+{@link #ABBR_GENERIC_TZ} or some other timezone presentation.
-     */
-    public static final String HOUR_MINUTE_GENERIC_TZ = "jmv";
-
-    /**
-     * {@icu} Constant for date skeleton with hour, minute, and timezone.
-     * @deprecated ICU 50 Use instead {@link #HOUR_MINUTE}+{@link #ABBR_SPECIFIC_TZ} or some other timezone presentation.
-     */
-    public static final String HOUR_MINUTE_TZ = "jmz";
-
-    /**
-     * {@icu} Constant for date skeleton with hour and generic timezone.
-     * @deprecated ICU 50 Use instead {@link #HOUR}+{@link #ABBR_GENERIC_TZ} or some other timezone presentation.
-     */
-    public static final String HOUR_GENERIC_TZ = "jv";
-
-    /**
-     * {@icu} Constant for date skeleton with hour and timezone.
-     * @deprecated ICU 50 Use instead {@link #HOUR}+{@link #ABBR_SPECIFIC_TZ} or some other timezone presentation.
-     */
-    public static final String HOUR_TZ = "jz";
-    /**
-     * Gets the time formatter with the default formatting style
-     * for the default locale.
-     * @return a time formatter.
-     * @stable ICU 2.0
-     */
-    public final static DateFormat getTimeInstance()
-    {
-        return new DateFormat(java.text.DateFormat.getTimeInstance(
-                java.text.DateFormat.DEFAULT,
-                ULocale.getDefault(Category.FORMAT).toLocale()));
-    }
-
-    /**
-     * Returns the time formatter with the given formatting style
-     * for the default locale.
-     * @param style the given formatting style. For example,
-     * SHORT for "h:mm a" in the US locale.
-     * @return a time formatter.
-     * @stable ICU 2.0
-     */
-    public final static DateFormat getTimeInstance(int style)
-    {
-        return new DateFormat(java.text.DateFormat.getTimeInstance(
-                getJDKFormatStyle(style),
-                ULocale.getDefault(Category.FORMAT).toLocale()));
-    }
-
-    /**
-     * Returns the time formatter with the given formatting style
-     * for the given locale.
-     * @param style the given formatting style. For example,
-     * SHORT for "h:mm a" in the US locale.
-     * @param aLocale the given locale.
-     * @return a time formatter.
-     * @stable ICU 2.0
-     */
-    public final static DateFormat getTimeInstance(int style,
-                                                 Locale aLocale)
-    {
-        return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(style), aLocale));
-    }
-
-    /**
-     * Returns the time formatter with the given formatting style
-     * for the given locale.
-     * @param style the given formatting style. For example,
-     * SHORT for "h:mm a" in the US locale.
-     * @param locale the given ulocale.
-     * @return a time formatter.
-     * @stable ICU 3.2
-     */
-    public final static DateFormat getTimeInstance(int style,
-                                                 ULocale locale)
-    {
-        return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(style), locale.toLocale()));
-    }
-
-    /**
-     * Returns the date formatter with the default formatting style
-     * for the default locale.
-     * @return a date formatter.
-     * @stable ICU 2.0
-     */
-    public final static DateFormat getDateInstance()
-    {
-        return new DateFormat(java.text.DateFormat.getDateInstance(
-                java.text.DateFormat.DEFAULT,
-                ULocale.getDefault(Category.FORMAT).toLocale()));
-    }
-
-    /**
-     * Returns the date formatter with the given formatting style
-     * for the default locale.
-     * @param style the given formatting style. For example,
-     * SHORT for "M/d/yy" in the US locale.
-     * @return a date formatter.
-     * @stable ICU 2.0
-     */
-    public final static DateFormat getDateInstance(int style)
-    {
-        return new DateFormat(java.text.DateFormat.getDateInstance(
-                getJDKFormatStyle(style),
-                ULocale.getDefault(Category.FORMAT).toLocale()));
-    }
-
-    /**
-     * Returns the date formatter with the given formatting style
-     * for the given locale.
-     * @param style the given formatting style. For example,
-     * SHORT for "M/d/yy" in the US locale.
-     * @param aLocale the given locale.
-     * @return a date formatter.
-     * @stable ICU 2.0
-     */
-    public final static DateFormat getDateInstance(int style,
-                                                 Locale aLocale)
-    {
-        return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(style), aLocale));
-    }
-
-    /**
-     * Returns the date formatter with the given formatting style
-     * for the given locale.
-     * @param style the given formatting style. For example,
-     * SHORT for "M/d/yy" in the US locale.
-     * @param locale the given ulocale.
-     * @return a date formatter.
-     * @stable ICU 3.2
-     */
-    public final static DateFormat getDateInstance(int style,
-                                                 ULocale locale)
-    {
-        return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(style), locale.toLocale()));
-    }
-
-    /**
-     * Returns the date/time formatter with the default formatting style
-     * for the default locale.
-     * @return a date/time formatter.
-     * @stable ICU 2.0
-     */
-    public final static DateFormat getDateTimeInstance()
-    {
-        return new DateFormat(java.text.DateFormat.getDateTimeInstance(
-                java.text.DateFormat.DEFAULT,
-                java.text.DateFormat.DEFAULT,
-                ULocale.getDefault(Category.FORMAT).toLocale()));
-    }
-
-    /**
-     * Returns the date/time formatter with the given date and time
-     * formatting styles for the default locale.
-     * @param dateStyle the given date formatting style. For example,
-     * SHORT for "M/d/yy" in the US locale.
-     * @param timeStyle the given time formatting style. For example,
-     * SHORT for "h:mm a" in the US locale.
-     * @return a date/time formatter.
-     * @stable ICU 2.0
-     */
-    public final static DateFormat getDateTimeInstance(int dateStyle,
-                                                       int timeStyle)
-    {
-        if (dateStyle != NONE) {
-            if (timeStyle != NONE) {
-                return new DateFormat(java.text.DateFormat.getDateTimeInstance(
-                        getJDKFormatStyle(dateStyle),
-                        getJDKFormatStyle(timeStyle),
-                        ULocale.getDefault(Category.FORMAT).toLocale()));
-            } else {
-                return new DateFormat(java.text.DateFormat.getDateInstance(
-                        getJDKFormatStyle(dateStyle),
-                        ULocale.getDefault(Category.FORMAT).toLocale()));
-            }
-        }
-        if (timeStyle != NONE) {
-            return new DateFormat(java.text.DateFormat.getTimeInstance(
-                    getJDKFormatStyle(timeStyle),
-                    ULocale.getDefault(Category.FORMAT).toLocale()));
-        }
-        return null;
-    }
-
-    /**
-     * Returns the date/time formatter with the given formatting styles
-     * for the given locale.
-     * @param dateStyle the given date formatting style.
-     * @param timeStyle the given time formatting style.
-     * @param aLocale the given locale.
-     * @return a date/time formatter.
-     * @stable ICU 2.0
-     */
-    public final static DateFormat getDateTimeInstance(
-        int dateStyle, int timeStyle, Locale aLocale)
-    {
-        if (dateStyle != NONE) {
-            if (timeStyle != NONE) {
-                return new DateFormat(java.text.DateFormat.getDateTimeInstance(getJDKFormatStyle(dateStyle), getJDKFormatStyle(timeStyle), aLocale));
-            } else {
-                return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(dateStyle), aLocale));
-            }
-        }
-        if (timeStyle != NONE) {
-            return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(timeStyle), aLocale));
-        }
-        return null;
-    }
-
-    /**
-     * Returns the date/time formatter with the given formatting styles
-     * for the given locale.
-     * @param dateStyle the given date formatting style.
-     * @param timeStyle the given time formatting style.
-     * @param locale the given ulocale.
-     * @return a date/time formatter.
-     * @stable ICU 3.2
-     */
-    public final static DateFormat getDateTimeInstance(
-        int dateStyle, int timeStyle, ULocale locale)
-    {
-        if (dateStyle != NONE) {
-            if (timeStyle != NONE) {
-                return new DateFormat(java.text.DateFormat.getDateTimeInstance(getJDKFormatStyle(dateStyle), getJDKFormatStyle(timeStyle), locale.toLocale()));
-            } else {
-                return new DateFormat(java.text.DateFormat.getDateInstance(getJDKFormatStyle(dateStyle), locale.toLocale()));
-            }
-        }
-        if (timeStyle != NONE) {
-            return new DateFormat(java.text.DateFormat.getTimeInstance(getJDKFormatStyle(timeStyle), locale.toLocale()));
-        }
-        return null;
-    }
-
-    /**
-     * Returns a default date/time formatter that uses the SHORT style for both the
-     * date and the time.
-     * @stable ICU 2.0
-     */
-    public final static DateFormat getInstance() {
-        return new DateFormat(java.text.DateFormat.getDateTimeInstance(
-                java.text.DateFormat.SHORT,
-                java.text.DateFormat.SHORT,
-                ULocale.getDefault(Category.FORMAT).toLocale()));
-    }
-
-    /**
-     * Returns the set of locales for which DateFormats are installed.
-     * @return the set of locales for which DateFormats are installed.
-     * @stable ICU 2.0
-     */
-    public static Locale[] getAvailableLocales()
-    {
-        return java.text.DateFormat.getAvailableLocales();
-    }
-
-    /**
-     * {@icu} Returns the set of locales for which DateFormats are installed.
-     * @return the set of locales for which DateFormats are installed.
-     * @draft ICU 3.2 (retain)
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static ULocale[] getAvailableULocales()
-    {
-        if (availableULocales == null) {
-            synchronized(DateFormat.class) {
-                if (availableULocales == null) {
-                    Locale[] locales = java.text.DateFormat.getAvailableLocales();
-                    availableULocales = new ULocale[locales.length];
-                    for (int i = 0; i < locales.length; ++i) {
-                        availableULocales[i] = ULocale.forLocale(locales[i]);
-                    }
-                }
-            }
-        }
-        return availableULocales;
-    }
-    private static volatile ULocale[] availableULocales;
-
-    /**
-     * Sets the calendar to be used by this date format.  Initially, the default
-     * calendar for the specified or default locale is used.
-     * @param newCalendar the new Calendar to be used by the date format
-     * @stable ICU 2.0
-     */
-    public void setCalendar(Calendar newCalendar)
-    {
-        dateFormat.setCalendar(newCalendar.calendar);
-    }
-
-    /**
-     * Returns the calendar associated with this date/time formatter.
-     * @return the calendar associated with this date/time formatter.
-     * @stable ICU 2.0
-     */
-    public Calendar getCalendar()
-    {
-        return new Calendar(dateFormat.getCalendar());
-    }
-
-    /**
-     * Sets the number formatter.
-     * @param newNumberFormat the given new NumberFormat.
-     * @stable ICU 2.0
-     */
-    public void setNumberFormat(NumberFormat newNumberFormat)
-    {
-        dateFormat.setNumberFormat(newNumberFormat.numberFormat);
-    }
-
-    /**
-     * Returns the number formatter which this date/time formatter uses to
-     * format and parse a time.
-     * @return the number formatter which this date/time formatter uses.
-     * @stable ICU 2.0
-     */
-    public NumberFormat getNumberFormat()
-    {
-        return new NumberFormat(dateFormat.getNumberFormat());
-    }
-
-    /**
-     * Sets the time zone for the calendar of this DateFormat object.
-     * @param zone the given new time zone.
-     * @stable ICU 2.0
-     */
-    public void setTimeZone(TimeZone zone)
-    {
-        dateFormat.setTimeZone(zone.timeZone);
-    }
-
-    /**
-     * Returns the time zone.
-     * @return the time zone associated with the calendar of DateFormat.
-     * @stable ICU 2.0
-     */
-    public TimeZone getTimeZone()
-    {
-        return new TimeZone(dateFormat.getTimeZone());
-    }
-
-    /**
-     * Specifies whether date/time parsing is to be lenient.  With
-     * lenient parsing, the parser may use heuristics to interpret inputs that
-     * do not precisely match this object's format.  With strict parsing,
-     * inputs must match this object's format.
-     * @param lenient when true, parsing is lenient
-     * @see com.ibm.icu.util.Calendar#setLenient
-     * @stable ICU 2.0
-     */
-    public void setLenient(boolean lenient)
-    {
-        dateFormat.setLenient(lenient);
-    }
-
-    /**
-     * Returns whether date/time parsing is lenient.
-     * @stable ICU 2.0
-     */
-    public boolean isLenient()
-    {
-        return dateFormat.isLenient();
-    }
-
-    /**
-     * Overrides hashCode.
-     * @stable ICU 2.0
-     */
-    public int hashCode() {
-        return dateFormat.hashCode();
-    }
-
-    /**
-     * Overrides equals.
-     * @stable ICU 2.0
-     */
-    public boolean equals(Object obj) {
-        try {
-            return dateFormat.equals(((DateFormat)obj).dateFormat);
-        }
-        catch (Exception e) {
-            return false;
-        }
-    }
-
-    /**
-     * Overrides clone.
-     * @stable ICU 2.0
-     */
-    public Object clone()
-    {
-        return new DateFormat((java.text.DateFormat)dateFormat.clone());
-    }
-
-    //-------------------------------------------------------------------------
-    // Public static interface for creating custon DateFormats for different
-    // types of Calendars.
-    //-------------------------------------------------------------------------
-
-    /**
-     * Creates a {@link DateFormat} object that can be used to format dates in
-     * the calendar system specified by <code>cal</code>.
-     * <p>
-     * @param cal   The calendar system for which a date format is desired.
-     *
-     * @param dateStyle The type of date format desired.  This can be
-     *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
-     *              etc.
-     *
-     * @param locale The locale for which the date format is desired.
-     * @stable ICU 2.0
-     */
-    static final public DateFormat getDateInstance(Calendar cal, int dateStyle, Locale locale)
-    {
-        DateFormat df = getDateInstance(dateStyle, locale);
-        df.setCalendar(cal);
-        return df;
-    }
-
-    /**
-     * Creates a {@link DateFormat} object that can be used to format dates in
-     * the calendar system specified by <code>cal</code>.
-     * <p>
-     * @param cal   The calendar system for which a date format is desired.
-     *
-     * @param dateStyle The type of date format desired.  This can be
-     *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
-     *              etc.
-     *
-     * @param locale The locale for which the date format is desired.
-     * @stable ICU 3.2
-     */
-    static final public DateFormat getDateInstance(Calendar cal, int dateStyle, ULocale locale)
-    {
-        DateFormat df = getDateInstance(dateStyle, locale);
-        df.setCalendar(cal);
-        return df;
-    }
-
-    /**
-     * Creates a {@link DateFormat} object that can be used to format times in
-     * the calendar system specified by <code>cal</code>.
-     * <p>
-     * <b>Note:</b> When this functionality is moved into the core JDK, this method
-     * will probably be replaced by a new overload of {@link DateFormat#getInstance}.
-     * <p>
-     * @param cal   The calendar system for which a time format is desired.
-     *
-     * @param timeStyle The type of time format desired.  This can be
-     *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
-     *              etc.
-     *
-     * @param locale The locale for which the time format is desired.
-     *
-     * @see DateFormat#getTimeInstance
-     * @stable ICU 2.0
-     */
-    static final public DateFormat getTimeInstance(Calendar cal, int timeStyle, Locale locale)
-    {
-        DateFormat df = getTimeInstance(timeStyle, locale);
-        df.setCalendar(cal);
-        return df;
-    }
-
-    /**
-     * Creates a {@link DateFormat} object that can be used to format times in
-     * the calendar system specified by <code>cal</code>.
-     * <p>
-     * <b>Note:</b> When this functionality is moved into the core JDK, this method
-     * will probably be replaced by a new overload of {@link DateFormat#getInstance}.
-     * <p>
-     * @param cal   The calendar system for which a time format is desired.
-     *
-     * @param timeStyle The type of time format desired.  This can be
-     *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
-     *              etc.
-     *
-     * @param locale The locale for which the time format is desired.
-     *
-     * @see DateFormat#getTimeInstance
-     * @stable ICU 3.2
-     */
-    static final public DateFormat getTimeInstance(Calendar cal, int timeStyle, ULocale locale)
-    {
-        DateFormat df = getTimeInstance(timeStyle, locale);
-        df.setCalendar(cal);
-        return df;
-    }
-
-    /**
-     * Creates a {@link DateFormat} object that can be used to format dates and times in
-     * the calendar system specified by <code>cal</code>.
-     * <p>
-     * <b>Note:</b> When this functionality is moved into the core JDK, this method
-     * will probably be replaced by a new overload of {@link DateFormat#getInstance}.
-     * <p>
-     * @param cal   The calendar system for which a date/time format is desired.
-     *
-     * @param dateStyle The type of date format desired.  This can be
-     *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
-     *              etc.
-     *
-     * @param timeStyle The type of time format desired.  This can be
-     *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
-     *              etc.
-     *
-     * @param locale The locale for which the date/time format is desired.
-     *
-     * @see DateFormat#getDateTimeInstance
-     * @stable ICU 2.0
-     */
-    static final public DateFormat getDateTimeInstance(Calendar cal, int dateStyle,
-                                                 int timeStyle, Locale locale)
-    {
-        DateFormat df = getDateTimeInstance(dateStyle, timeStyle, locale);
-        df.setCalendar(cal);
-        return df;
-    }
-
-    /**
-     * Creates a {@link DateFormat} object that can be used to format dates and times in
-     * the calendar system specified by <code>cal</code>.
-     * <p>
-     * <b>Note:</b> When this functionality is moved into the core JDK, this method
-     * will probably be replaced by a new overload of {@link DateFormat#getInstance}.
-     * <p>
-     * @param cal   The calendar system for which a date/time format is desired.
-     *
-     * @param dateStyle The type of date format desired.  This can be
-     *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
-     *              etc.
-     *
-     * @param timeStyle The type of time format desired.  This can be
-     *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
-     *              etc.
-     *
-     * @param locale The locale for which the date/time format is desired.
-     *
-     * @see DateFormat#getDateTimeInstance
-     * @stable ICU 3.2
-     */
-    static final public DateFormat getDateTimeInstance(Calendar cal, int dateStyle,
-                                                 int timeStyle, ULocale locale)
-    {
-        DateFormat df = getDateTimeInstance(dateStyle, timeStyle, locale);
-        df.setCalendar(cal);
-        return df;
-    }
-
-    /**
-     * Convenience overload.
-     * @stable ICU 2.0
-     */
-    static final public DateFormat getInstance(Calendar cal, Locale locale) {
-        return getDateTimeInstance(cal, DateFormat.MEDIUM, DateFormat.SHORT, locale);
-    }
-
-    /**
-     * Convenience overload.
-     * @stable ICU 3.2
-     * @provisional This API might change or be removed in a future release.
-     */
-    static final public DateFormat getInstance(Calendar cal, ULocale locale) {
-        return getDateTimeInstance(cal, DateFormat.MEDIUM, DateFormat.SHORT, locale);
-    }
-
-    /**
-     * Convenience overload.
-     * @stable ICU 2.0
-     */
-    static final public DateFormat getInstance(Calendar cal) {
-        return getInstance(cal, ULocale.getDefault(Category.FORMAT));
-    }
-
-    /**
-     * Convenience overload.
-     * @stable ICU 2.0
-     */
-    static final public DateFormat getDateInstance(Calendar cal, int dateStyle) {
-        return getDateInstance(cal, dateStyle, ULocale.getDefault(Category.FORMAT));
-    }
-
-    /**
-     * Convenience overload.
-     * @stable ICU 2.0
-     */
-    static final public DateFormat getTimeInstance(Calendar cal, int timeStyle) {
-        return getTimeInstance(cal, timeStyle, ULocale.getDefault(Category.FORMAT));
-    }
-
-    /**
-     * Convenience overload.
-     * @stable ICU 2.0
-     */
-    static final public DateFormat getDateTimeInstance(Calendar cal, int dateStyle, int timeStyle) {
-        return getDateTimeInstance(cal, dateStyle, timeStyle, ULocale.getDefault(Category.FORMAT));
-    }
-
-//    /**
-//     * {@icu} Convenience overload.
-//     * @stable ICU 4.0
-//     */
-//    public final static DateFormat getPatternInstance(String pattern) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Convenience overload.
-//     * @stable ICU 4.0
-//     */
-//    public final static DateFormat getPatternInstance(String pattern, Locale locale) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns a {@link DateFormat} object that can be used to format dates and times in
-//     * the given locale.
-//     * <p>
-//     * <b>Note:</b> When this functionality is moved into the core JDK, this method
-//     * will probably be replaced by a new overload of {@link DateFormat#getInstance}.
-//     * <p>
-//     *
-//     * @param pattern The pattern that selects the fields to be formatted. (Uses the
-//     *              {@link DateTimePatternGenerator}.) This can be {@link DateFormat#ABBR_MONTH},
-//     *              {@link DateFormat#MONTH_WEEKDAY_DAY}, etc.
-//     *
-//     * @param locale The locale for which the date/time format is desired.
-//     *
-//     * @stable ICU 4.0
-//     */
-//    public final static DateFormat getPatternInstance(String pattern, ULocale locale) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Convenience overload.
-//     * @stable ICU 4.0
-//     */
-//    public final static DateFormat getPatternInstance(Calendar cal, String pattern, Locale locale) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Creates a {@link DateFormat} object that can be used to format dates and
-//     * times in the calendar system specified by <code>cal</code>.
-//     *
-//     * <p><b>Note:</b> When this functionality is moved into the core JDK, this method
-//     * will probably be replaced by a new overload of {@link DateFormat#getInstance}.
-//     *
-//     * @param cal   The calendar system for which a date/time format is desired.
-//     *
-//     * @param pattern The pattern that selects the fields to be formatted. (Uses the
-//     *              {@link DateTimePatternGenerator}.)  This can be
-//     *              {@link DateFormat#ABBR_MONTH}, {@link DateFormat#MONTH_WEEKDAY_DAY},
-//     *              etc.
-//     *
-//     * @param locale The locale for which the date/time format is desired.
-//     *
-//     * @stable ICU 4.0
-//     */
-//    public final static DateFormat getPatternInstance(
-//        Calendar cal, String pattern, ULocale locale) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * The instances of this inner class are used as attribute keys and values
-     * in AttributedCharacterIterator that
-     * DateFormat.formatToCharacterIterator() method returns.
-     *
-     * <p>There is no public constructor to this class, the only instances are the
-     * constants defined here.
-     * <p>
-     * @stable ICU 3.8
-     */
-    public static class Field extends Format.Field {
-
-        private static final long serialVersionUID = -3627456821000730829L;
-
-        // Max number of calendar fields
-        private static final int CAL_FIELD_COUNT;
-
-        // Table for mapping calendar field number to DateFormat.Field
-        private static final Field[] CAL_FIELDS;
-
-        // Map for resolving DateFormat.Field by name
-        private static final Map<String, Field> FIELD_NAME_MAP;
-
-        static {
-            Calendar cal = Calendar.getInstance();
-            CAL_FIELD_COUNT = cal.getFieldCount();
-            CAL_FIELDS = new Field[CAL_FIELD_COUNT];
-            FIELD_NAME_MAP = new HashMap<String, Field>(CAL_FIELD_COUNT);
-        }
-
-        // Java fields -------------------
-
-        /**
-         * Constant identifying the time of day indicator(am/pm).
-         * @stable ICU 3.8
-         */
-        public static final Field AM_PM = new Field("am pm", Calendar.AM_PM);
-
-        /**
-         * Constant identifying the day of month field.
-         * @stable ICU 3.8
-         */
-        public static final Field DAY_OF_MONTH = new Field("day of month", Calendar.DAY_OF_MONTH);
-
-        /**
-         * Constant identifying the day of week field.
-         * @stable ICU 3.8
-         */
-        public static final Field DAY_OF_WEEK = new Field("day of week", Calendar.DAY_OF_WEEK);
-
-        /**
-         * Constant identifying the day of week in month field.
-         * @stable ICU 3.8
-         */
-        public static final Field DAY_OF_WEEK_IN_MONTH =
-            new Field("day of week in month", Calendar.DAY_OF_WEEK_IN_MONTH);
-
-        /**
-         * Constant identifying the day of year field.
-         * @stable ICU 3.8
-         */
-        public static final Field DAY_OF_YEAR = new Field("day of year", Calendar.DAY_OF_YEAR);
-
-        /**
-         * Constant identifying the era field.
-         * @stable ICU 3.8
-         */
-        public static final Field ERA = new Field("era", Calendar.ERA);
-
-        /**
-         * Constant identifying the hour(0-23) of day field.
-         * @stable ICU 3.8
-         */
-        public static final Field HOUR_OF_DAY0 = new Field("hour of day", Calendar.HOUR_OF_DAY);
-
-        /**
-         * Constant identifying the hour(1-24) of day field.
-         * @stable ICU 3.8
-         */
-        public static final Field HOUR_OF_DAY1 = new Field("hour of day 1", -1);
-
-        /**
-         * Constant identifying the hour(0-11) field.
-         * @stable ICU 3.8
-         */
-        public static final Field HOUR0 = new Field("hour", Calendar.HOUR);
-
-        /**
-         * Constant identifying the hour(1-12) field.
-         * @stable ICU 3.8
-         */
-        public static final Field HOUR1 = new Field("hour 1", -1);
-
-        /**
-         * Constant identifying the millisecond field.
-         * @stable ICU 3.8
-         */
-        public static final Field MILLISECOND = new Field("millisecond", Calendar.MILLISECOND);
-
-        /**
-         * Constant identifying the minute field.
-         * @stable ICU 3.8
-         */
-        public static final Field MINUTE = new Field("minute", Calendar.MINUTE);
-
-        /**
-         * Constant identifying the month field.
-         * @stable ICU 3.8
-         */
-        public static final Field MONTH = new Field("month", Calendar.MONTH);
-
-        /**
-         * Constant identifying the second field.
-         * @stable ICU 3.8
-         */
-        public static final Field SECOND = new Field("second", Calendar.SECOND);
-
-        /**
-         * Constant identifying the time zone field.
-         * @stable ICU 3.8
-         */
-        public static final Field TIME_ZONE = new Field("time zone", -1);
-
-        /**
-         * Constant identifying the week of month field.
-         * @stable ICU 3.8
-         */
-        public static final Field WEEK_OF_MONTH =
-            new Field("week of month", Calendar.WEEK_OF_MONTH);
-
-        /**
-         * Constant identifying the week of year field.
-         * @stable ICU 3.8
-         */
-        public static final Field WEEK_OF_YEAR = new Field("week of year", Calendar.WEEK_OF_YEAR);
-
-        /**
-         * Constant identifying the year field.
-         * @stable ICU 3.8
-         */
-        public static final Field YEAR = new Field("year", Calendar.YEAR);
-
-
-        // ICU only fields -------------------
-
-//        /**
-//         * Constant identifying the local day of week field.
-//         * @stable ICU 3.8
-//         */
-//        public static final Field DOW_LOCAL = new Field("local day of week", Calendar.DOW_LOCAL);
-
-//        /**
-//         * Constant identifying the extended year field.
-//         * @stable ICU 3.8
-//         */
-//        public static final Field EXTENDED_YEAR = new Field("extended year", 
-//                                                            Calendar.EXTENDED_YEAR);
-
-//        /**
-//         * Constant identifying the Julian day field.
-//         * @stable ICU 3.8
-//         */
-//        public static final Field JULIAN_DAY = new Field("Julian day", Calendar.JULIAN_DAY);
-
-//        /**
-//         * Constant identifying the milliseconds in day field.
-//         * @stable ICU 3.8
-//         */
-//        public static final Field MILLISECONDS_IN_DAY =
-//            new Field("milliseconds in day", Calendar.MILLISECONDS_IN_DAY);
-
-//        /**
-//         * Constant identifying the year used with week of year field.
-//         * @stable ICU 3.8
-//         */
-//        public static final Field YEAR_WOY = new Field("year for week of year", Calendar.YEAR_WOY);
-
-//        /**
-//         * Constant identifying the quarter field.
-//         * @stable ICU 3.8
-//         */
-//        public static final Field QUARTER = new Field("quarter", -1);
-
-        // Stand alone types are variants for its base types.  So we do not define Field for
-        // them.
-        /*
-        public static final Field STANDALONE_DAY =
-            new Field("stand alone day of week", Calendar.DAY_OF_WEEK);
-        public static final Field STANDALONE_MONTH = new Field("stand alone month", Calendar.MONTH);
-        public static final Field STANDALONE_QUARTER = new Field("stand alone quarter", -1);
-        */
-
-        // Corresponding calendar field
-        private final int calendarField;
-
-        /**
-         * Constructs a <code>DateFormat.Field</code> with the given name and
-         * the <code>Calendar</code> field which this attribute represents.  Use -1 for
-         * <code>calendarField</code> if this field does not have a corresponding
-         * <code>Calendar</code> field.
-         *
-         * @param name          Name of the attribute
-         * @param calendarField <code>Calendar</code> field constant
-         *
-         * @stable ICU 3.8
-         */
-        protected Field(String name, int calendarField) {
-            super(name);
-            this.calendarField = calendarField;
-            if (this.getClass() == DateFormat.Field.class) {
-                FIELD_NAME_MAP.put(name, this);
-                if (calendarField >= 0 && calendarField < CAL_FIELD_COUNT) {
-                    CAL_FIELDS[calendarField] = this;
-                }
-            }
-        }
-
-        /**
-         * Returns the <code>Field</code> constant that corresponds to the <code>
-         * Calendar</code> field <code>calendarField</code>.  If there is no
-         * corresponding <code>Field</code> is available, null is returned.
-         *
-         * @param calendarField <code>Calendar</code> field constant
-         * @return <code>Field</code> associated with the <code>calendarField</code>,
-         * or null if no associated <code>Field</code> is available.
-         * @throws IllegalArgumentException if <code>calendarField</code> is not
-         * a valid <code>Calendar</code> field constant.
-         *
-         * @stable ICU 3.8
-         */
-        public static DateFormat.Field ofCalendarField(int calendarField) {
-            if (calendarField < 0 || calendarField >= CAL_FIELD_COUNT) {
-                throw new IllegalArgumentException("Calendar field number is out of range");
-            }
-            return CAL_FIELDS[calendarField];
-        }
-
-        /**
-         * Returns the <code>Calendar</code> field associated with this attribute.
-         * If there is no corresponding <code>Calendar</code> available, this will
-         * return -1.
-         *
-         * @return <code>Calendar</code> constant for this attribute.
-         *
-         * @stable ICU 3.8
-         */
-        public int getCalendarField() {
-            return calendarField;
-        }
-
-        /**
-         * Resolves instances being deserialized to the predefined constants.
-         *
-         * @throws InvalidObjectException if the constant could not be resolved.
-         *
-         * @stable ICU 3.8
-         */
-        protected Object readResolve() throws InvalidObjectException {
-            ///CLOVER:OFF
-            if (this.getClass() != DateFormat.Field.class) {
-                throw new InvalidObjectException(
-                    "A subclass of DateFormat.Field must implement readResolve.");
-            }
-            ///CLOVER:ON
-            Object o = FIELD_NAME_MAP.get(this.getName());
-            ///CLOVER:OFF
-            if (o == null) {
-                throw new InvalidObjectException("Unknown attribute name.");
-            }
-            ///CLOVER:ON
-            return o;
-        }
-    }
-
-    private static int getJDKFormatStyle(int icuFormatStyle) {
-        switch (icuFormatStyle) {
-        case DateFormat.FULL:
-            return java.text.DateFormat.FULL;
-        case DateFormat.LONG:
-            return java.text.DateFormat.LONG;
-        case DateFormat.MEDIUM:
-            return java.text.DateFormat.MEDIUM;
-        case DateFormat.SHORT:
-            return java.text.DateFormat.SHORT;
-        default:
-            throw new UnsupportedOperationException("Style not supported by com.ibm.icu.base");
-        }
-    }
-
-
-    protected static FieldPosition toJDKFieldPosition(FieldPosition icuPos) {
-        if (icuPos == null) {
-            return null;
-        }
-
-        int fieldID = icuPos.getField();
-        Format.Field fieldAttribute = icuPos.getFieldAttribute();
-
-        FieldPosition jdkPos = null;
-
-        if (fieldID >= 0) {
-            switch (fieldID) {
-            case ERA_FIELD:
-                fieldID = java.text.DateFormat.ERA_FIELD;
-                break;
-            case YEAR_FIELD:
-                fieldID = java.text.DateFormat.YEAR_FIELD;
-                break;
-            case MONTH_FIELD:
-                fieldID = java.text.DateFormat.MONTH_FIELD;
-                break;
-            case DATE_FIELD:
-                fieldID = java.text.DateFormat.DATE_FIELD;
-                break;
-            case HOUR_OF_DAY1_FIELD:
-                fieldID = java.text.DateFormat.HOUR_OF_DAY1_FIELD;
-                break;
-            case HOUR_OF_DAY0_FIELD:
-                fieldID = java.text.DateFormat.HOUR_OF_DAY0_FIELD;
-                break;
-            case MINUTE_FIELD:
-                fieldID = java.text.DateFormat.MINUTE_FIELD;
-                break;
-            case SECOND_FIELD:
-                fieldID = java.text.DateFormat.SECOND_FIELD;
-                break;
-            case FRACTIONAL_SECOND_FIELD: // MILLISECOND_FIELD
-                fieldID = java.text.DateFormat.MILLISECOND_FIELD;
-                break;
-            case DAY_OF_WEEK_FIELD:
-                fieldID = java.text.DateFormat.DAY_OF_WEEK_FIELD;
-                break;
-            case DAY_OF_YEAR_FIELD:
-                fieldID = java.text.DateFormat.DAY_OF_YEAR_FIELD;
-                break;
-            case DAY_OF_WEEK_IN_MONTH_FIELD:
-                fieldID = java.text.DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD;
-                break;
-            case WEEK_OF_YEAR_FIELD:
-                fieldID = java.text.DateFormat.WEEK_OF_YEAR_FIELD;
-                break;
-            case WEEK_OF_MONTH_FIELD:
-                fieldID = java.text.DateFormat.WEEK_OF_MONTH_FIELD;
-                break;
-            case AM_PM_FIELD:
-                fieldID = java.text.DateFormat.AM_PM_FIELD;
-                break;
-            case HOUR1_FIELD:
-                fieldID = java.text.DateFormat.HOUR1_FIELD;
-                break;
-            case HOUR0_FIELD:
-                fieldID = java.text.DateFormat.HOUR0_FIELD;
-                break;
-            case TIMEZONE_FIELD:
-                fieldID = java.text.DateFormat.TIMEZONE_FIELD;
-                break;
-
-            case YEAR_WOY_FIELD:
-            case DOW_LOCAL_FIELD:
-            case EXTENDED_YEAR_FIELD:
-            case JULIAN_DAY_FIELD:
-            case MILLISECONDS_IN_DAY_FIELD:
-            case TIMEZONE_RFC_FIELD:
-            case TIMEZONE_GENERIC_FIELD:
-            case STANDALONE_DAY_FIELD:
-            case STANDALONE_MONTH_FIELD:
-            case QUARTER_FIELD:
-            case STANDALONE_QUARTER_FIELD:
-            case TIMEZONE_SPECIAL_FIELD:
-                throw new UnsupportedOperationException("Format Field ID not supported by com.ibm.icu.base");
-
-            default:
-                // just let it go
-                break;
-            }
-        }
-
-        if (fieldAttribute != null) {
-            // map field
-            if (fieldAttribute.equals(Field.AM_PM)) {
-                fieldAttribute = java.text.DateFormat.Field.AM_PM;
-            } else if (fieldAttribute.equals(Field.DAY_OF_MONTH)) {
-                fieldAttribute = java.text.DateFormat.Field.DAY_OF_MONTH;
-            } else if (fieldAttribute.equals(Field.DAY_OF_WEEK)) {
-                fieldAttribute = java.text.DateFormat.Field.DAY_OF_WEEK;
-            } else if (fieldAttribute.equals(Field.DAY_OF_WEEK_IN_MONTH)) {
-                fieldAttribute = java.text.DateFormat.Field.DAY_OF_WEEK_IN_MONTH;
-            } else if (fieldAttribute.equals(Field.DAY_OF_YEAR)) {
-                fieldAttribute = java.text.DateFormat.Field.DAY_OF_YEAR;
-            } else if (fieldAttribute.equals(Field.ERA)) {
-                fieldAttribute = java.text.DateFormat.Field.ERA;
-            } else if (fieldAttribute.equals(Field.HOUR_OF_DAY0)) {
-                fieldAttribute = java.text.DateFormat.Field.HOUR_OF_DAY0;
-            } else if (fieldAttribute.equals(Field.HOUR_OF_DAY1)) {
-                fieldAttribute = java.text.DateFormat.Field.HOUR_OF_DAY1;
-            } else if (fieldAttribute.equals(Field.HOUR0)) {
-                fieldAttribute = java.text.DateFormat.Field.HOUR0;
-            } else if (fieldAttribute.equals(Field.HOUR1)) {
-                fieldAttribute = java.text.DateFormat.Field.HOUR1;
-            } else if (fieldAttribute.equals(Field.MILLISECOND)) {
-                fieldAttribute = java.text.DateFormat.Field.MILLISECOND;
-            } else if (fieldAttribute.equals(Field.MINUTE)) {
-                fieldAttribute = java.text.DateFormat.Field.MINUTE;
-            } else if (fieldAttribute.equals(Field.MONTH)) {
-                fieldAttribute = java.text.DateFormat.Field.MONTH;
-            } else if (fieldAttribute.equals(Field.SECOND)) {
-                fieldAttribute = java.text.DateFormat.Field.SECOND;
-            } else if (fieldAttribute.equals(Field.TIME_ZONE)) {
-                fieldAttribute = java.text.DateFormat.Field.TIME_ZONE;
-            } else if (fieldAttribute.equals(Field.WEEK_OF_MONTH)) {
-                fieldAttribute = java.text.DateFormat.Field.WEEK_OF_MONTH;
-            } else if (fieldAttribute.equals(Field.WEEK_OF_YEAR)) {
-                fieldAttribute = java.text.DateFormat.Field.WEEK_OF_YEAR;
-            } else if (fieldAttribute.equals(Field.YEAR)) {
-                fieldAttribute = java.text.DateFormat.Field.YEAR;
-            }
-//            else if (fieldAttribute.equals(Field.DOW_LOCAL)
-//                    || fieldAttribute.equals(Field.EXTENDED_YEAR)
-//                    || fieldAttribute.equals(Field.JULIAN_DAY)
-//                    || fieldAttribute.equals(Field.MILLISECONDS_IN_DAY)
-//                    || fieldAttribute.equals(Field.YEAR_WOY)
-//                    || fieldAttribute.equals(Field.QUARTER)) {
-//                // Not supported
-//                throw new UnsupportedOperationException("Format Field not supported by com.ibm.icu.base");
-//            }
-
-            jdkPos = new FieldPosition(fieldAttribute, fieldID);
-        } else {
-            jdkPos = new FieldPosition(fieldID);
-        }
-
-        jdkPos.setBeginIndex(icuPos.getBeginIndex());
-        jdkPos.setEndIndex(icuPos.getEndIndex());
-
-        return jdkPos;
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormatSymbols.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormatSymbols.java
deleted file mode 100644
index b14f26b..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DateFormatSymbols.java
+++ /dev/null
@@ -1,845 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 1996-2012, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.text;
-
-import java.io.Serializable;
-import java.util.Locale;
-
-import com.ibm.icu.util.ULocale;
-import com.ibm.icu.util.ULocale.Category;
-
-/**
- * {@icuenhanced java.text.DateFormatSymbols}.{@icu _usage_}
- *
- * <p><code>DateFormatSymbols</code> is a public class for encapsulating
- * localizable date-time formatting data, such as the names of the
- * months, the names of the days of the week, and the time zone data.
- * <code>DateFormat</code> and <code>SimpleDateFormat</code> both use
- * <code>DateFormatSymbols</code> to encapsulate this information.
- *
- * <p>Typically you shouldn't use <code>DateFormatSymbols</code> directly.
- * Rather, you are encouraged to create a date-time formatter with the
- * <code>DateFormat</code> class's factory methods: <code>getTimeInstance</code>,
- * <code>getDateInstance</code>, or <code>getDateTimeInstance</code>.
- * These methods automatically create a <code>DateFormatSymbols</code> for
- * the formatter so that you don't have to. After the
- * formatter is created, you may modify its format pattern using the
- * <code>setPattern</code> method. For more information about
- * creating formatters using <code>DateFormat</code>'s factory methods,
- * see {@link DateFormat}.
- *
- * <p>If you decide to create a date-time formatter with a specific
- * format pattern for a specific locale, you can do so with:
- * <blockquote>
- * <pre>
- * new SimpleDateFormat(aPattern, new DateFormatSymbols(aLocale)).
- * </pre>
- * </blockquote>
- *
- * <p><code>DateFormatSymbols</code> objects are clonable. When you obtain
- * a <code>DateFormatSymbols</code> object, feel free to modify the
- * date-time formatting data. For instance, you can replace the localized
- * date-time format pattern characters with the ones that you feel easy
- * to remember. Or you can change the representative cities
- * to your favorite ones.
- *
- * <p>New <code>DateFormatSymbols</code> subclasses may be added to support
- * <code>SimpleDateFormat</code> for date-time formatting for additional locales.
- *
- * @see          DateFormat
- * @see          SimpleDateFormat
- * @see          com.ibm.icu.util.SimpleTimeZone
- * @author       Chen-Lieh Huang
- * @stable ICU 2.0
- */
-public class DateFormatSymbols implements Serializable, Cloneable {
-
-    private static final long serialVersionUID = 1L;
-    
-    /** @internal */
-    public java.text.DateFormatSymbols dfs;
-        
-    /** @internal */
-    public DateFormatSymbols(java.text.DateFormatSymbols delegate) {
-        this.dfs = delegate;
-    }
-
-    // TODO make sure local pattern char string is 18 characters long,
-    // that is, that it encompasses the new 'u' char for
-    // EXTENDED_YEAR.  Two options: 1. Make sure resource data is
-    // correct; 2. Make code add in 'u' at end if len == 17.
-
-    // Constants for context
-    /**
-     * {@icu} Constant for context.
-     * @stable ICU 3.6
-     */
-    public static final int FORMAT = 0;
-
-    /**
-     * {@icu} Constant for context.
-     * @stable ICU 3.6
-     */
-    public static final int STANDALONE = 1;
-
-    /**
-     * {@icu} Constant for context.
-     * @internal
-     * @deprecated This API is ICU internal only.
-     */
-    public static final int DT_CONTEXT_COUNT = 2;
-
-    // Constants for width
-
-    /**
-     * {@icu} Constant for width.
-     * @stable ICU 3.6
-     */
-    public static final int ABBREVIATED = 0;
-
-    /**
-     * {@icu} Constant for width.
-     * @stable ICU 3.6
-     */
-    public static final int WIDE = 1;
-
-    /**
-     * {@icu} Constant for width.
-     * @stable ICU 3.6
-     */
-    public static final int NARROW = 2;
-
-    /**
-     * {@icu} Constant for width.
-     * @internal
-     * @deprecated This API is ICU internal only.
-     */
-    public static final int DT_WIDTH_COUNT = 3;
-
-    /**
-     * Constructs a DateFormatSymbols object by loading format data from
-     * resources for the default locale.
-     *
-     * @throws java.util.MissingResourceException if the resources for the default locale
-     *          cannot be found or cannot be loaded.
-     * @stable ICU 2.0
-     */
-    public DateFormatSymbols()
-    {
-        this(new java.text.DateFormatSymbols(ULocale.getDefault(Category.FORMAT).toLocale()));
-    }
-
-    /**
-     * Constructs a DateFormatSymbols object by loading format data from
-     * resources for the given locale.
-     *
-     * @throws java.util.MissingResourceException if the resources for the specified
-     *          locale cannot be found or cannot be loaded.
-     * @stable ICU 2.0
-     */
-    public DateFormatSymbols(Locale locale)
-    {
-        this(new java.text.DateFormatSymbols(locale));
-    }
-
-    /**
-     * {@icu} Constructs a DateFormatSymbols object by loading format data from
-     * resources for the given ulocale.
-     *
-     * @throws java.util.MissingResourceException if the resources for the specified
-     *          locale cannot be found or cannot be loaded.
-     * @stable ICU 3.2
-     */
-    public DateFormatSymbols(ULocale locale)
-    {
-        this(new java.text.DateFormatSymbols(locale.toLocale()));
-    }
-
-    /**
-     * Returns a DateFormatSymbols instance for the default locale.
-     *
-     * {@icunote} Unlike <code>java.text.DateFormatSymbols#getInstance</code>,
-     * this method simply returns <code>new com.ibm.icu.text.DateFormatSymbols()</code>.
-     * ICU does not support <code>DateFormatSymbolsProvider</code> introduced in Java 6
-     * or its equivalent implementation for now.
-     *
-     * @return A DateFormatSymbols instance.
-     * @stable ICU 3.8
-     */
-    public static DateFormatSymbols getInstance() {
-        return new DateFormatSymbols();
-    }
-
-    /**
-     * Returns a DateFormatSymbols instance for the given locale.
-     *
-     * {@icunote} Unlike <code>java.text.DateFormatSymbols#getInstance</code>,
-     * this method simply returns <code>new com.ibm.icu.text.DateFormatSymbols(locale)</code>.
-     * ICU does not support <code>DateFormatSymbolsProvider</code> introduced in Java 6
-     * or its equivalent implementation for now.
-     *
-     * @param locale the locale.
-     * @return A DateFormatSymbols instance.
-     * @stable ICU 3.8
-     */
-    public static DateFormatSymbols getInstance(Locale locale) {
-        return new DateFormatSymbols(new java.text.DateFormatSymbols(locale));
-    }
-
-    /**
-     * {@icu} Returns a DateFormatSymbols instance for the given locale.
-     *
-     * {@icunote} Unlike <code>java.text.DateFormatSymbols#getInstance</code>,
-     * this method simply returns <code>new com.ibm.icu.text.DateFormatSymbols(locale)</code>.
-     * ICU does not support <code>DateFormatSymbolsProvider</code> introduced in Java 6
-     * or its equivalent implementation for now.
-     *
-     * @param locale the locale.
-     * @return A DateFormatSymbols instance.
-     * @stable ICU 3.8
-     */
-    public static DateFormatSymbols getInstance(ULocale locale) {
-        return new DateFormatSymbols(new java.text.DateFormatSymbols(locale.toLocale()));
-    }
-
-    /**
-     * Returns an array of all locales for which the <code>getInstance</code> methods of
-     * this class can return localized instances.
-     *
-     * {@icunote} Unlike <code>java.text.DateFormatSymbols#getAvailableLocales</code>,
-     * this method simply returns the array of <code>Locale</code>s available in this
-     * class.  ICU does not support <code>DateFormatSymbolsProvider</code> introduced in
-     * Java 6 or its equivalent implementation for now.
-     *
-     * @return An array of <code>Locale</code>s for which localized
-     * <code>DateFormatSymbols</code> instances are available.
-     * @stable ICU 3.8
-     */
-    public static Locale[] getAvailableLocales() {
-        return java.text.DateFormat.getAvailableLocales();
-    }
-
-    /**
-     * {@icu} Returns an array of all locales for which the <code>getInstance</code>
-     * methods of this class can return localized instances.
-     *
-     * {@icunote} Unlike <code>java.text.DateFormatSymbols#getAvailableLocales</code>,
-     * this method simply returns the array of <code>ULocale</code>s available in this
-     * class.  ICU does not support <code>DateFormatSymbolsProvider</code> introduced in
-     * Java 6 or its equivalent implementation for now.
-     *
-     * @return An array of <code>ULocale</code>s for which localized
-     * <code>DateFormatSymbols</code> instances are available.
-     * @draft ICU 3.8 (retain)
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static ULocale[] getAvailableULocales() {
-        Locale[] locales = getAvailableLocales();
-        ULocale[] ulocales = new ULocale[locales.length];
-        for (int i = 0; i < locales.length; ++i) {
-            ulocales[i] = ULocale.forLocale(locales[i]);
-        }
-        return ulocales;
-    }
-
-    /**
-     * Returns era strings. For example: "AD" and "BC".
-     * @return the era strings.
-     * @stable ICU 2.0
-     */
-    public String[] getEras() {
-        return dfs.getEras();
-    }
-
-    /**
-     * Sets era strings. For example: "AD" and "BC".
-     * @param newEras the new era strings.
-     * @stable ICU 2.0
-     */
-    public void setEras(String[] newEras) {
-        dfs.setEras(newEras);
-    }
-
-    /**
-     * {@icu} Returns era name strings. For example: "Anno Domini" and "Before Christ".
-     * @return the era strings.
-     * @stable ICU 3.4
-     */
-    public String[] getEraNames() {
-        return getEras(); // Java has no distinction between era strings and era name strings
-    }
-
-    /**
-     * {@icu} Sets era name strings. For example: "Anno Domini" and "Before Christ".
-     * @param newEraNames the new era strings.
-     * @stable ICU 3.8
-     */
-    public void setEraNames(String[] newEraNames) {
-        setEras(newEraNames); // Java has no distinction between era strings and era name strings
-    }
-
-    /**
-     * Returns month strings. For example: "January", "February", etc.
-     * @return the month strings.
-     * @stable ICU 2.0
-     */
-    public String[] getMonths() {
-        return dfs.getMonths();
-    }
-
-    /**
-     * Returns month strings. For example: "January", "February", etc.
-     * @param context    The month context, FORMAT or STANDALONE.
-     * @param width      The width or the returned month string,
-     *                   either WIDE, ABBREVIATED, or NARROW.
-     * @return the month strings.
-     * @stable ICU 3.4
-     */
-    public String[] getMonths(int context, int width) {
-        // JDK does not support context / narrow months
-        switch (width) {
-        case WIDE:
-            return dfs.getMonths();
-
-        case ABBREVIATED:
-        case NARROW:
-            return dfs.getShortMonths();
-
-        default:
-            throw new IllegalArgumentException("Unsupported width argument value");
-        }
-    }
-
-    /**
-     * Sets month strings. For example: "January", "February", etc.
-     * @param newMonths the new month strings.
-     * @stable ICU 2.0
-     */
-    public void setMonths(String[] newMonths) {
-        dfs.setMonths(newMonths);
-    }
-
-    /**
-     * Sets month strings. For example: "January", "February", etc.
-     * @param newMonths the new month strings.
-     * @param context    The formatting context, FORMAT or STANDALONE.
-     * @param width      The width of the month string,
-     *                   either WIDE, ABBREVIATED, or NARROW.
-     * @stable ICU 3.8
-     */
-    public void setMonths(String[] newMonths, int context, int width) {
-        // JDK does not support context / narrow months
-        switch (width) {
-        case WIDE:
-            dfs.setMonths(newMonths);
-            break;
-
-        case ABBREVIATED:
-        case NARROW:
-            dfs.setShortMonths(newMonths);
-            break;
-
-        default:
-            throw new IllegalArgumentException("Unsupported width argument value");
-        }
-    }
-
-    /**
-     * Returns short month strings. For example: "Jan", "Feb", etc.
-     * @return the short month strings.
-     * @stable ICU 2.0
-     */
-    public String[] getShortMonths() {
-        return dfs.getShortMonths();
-    }
-
-    /**
-     * Sets short month strings. For example: "Jan", "Feb", etc.
-     * @param newShortMonths the new short month strings.
-     * @stable ICU 2.0
-     */
-    public void setShortMonths(String[] newShortMonths) {
-        dfs.setShortMonths(newShortMonths);
-    }
-
-    /**
-     * Returns weekday strings. For example: "Sunday", "Monday", etc.
-     * @return the weekday strings. Use <code>Calendar.SUNDAY</code>,
-     * <code>Calendar.MONDAY</code>, etc. to index the result array.
-     * @stable ICU 2.0
-     */
-    public String[] getWeekdays() {
-        return dfs.getWeekdays();
-    }
-
-    /**
-     * Returns weekday strings. For example: "Sunday", "Monday", etc.
-     * @return the weekday strings. Use <code>Calendar.SUNDAY</code>,
-     * <code>Calendar.MONDAY</code>, etc. to index the result array.
-     * @param context    Formatting context, either FORMAT or STANDALONE.
-     * @param width      Width of strings to be returned, either
-     *                   WIDE, ABBREVIATED, or NARROW
-     * @stable ICU 3.4
-     */
-    public String[] getWeekdays(int context, int width) {
-        // JDK does not support context / narrow weekdays
-        switch (width) {
-        case WIDE:
-            return dfs.getWeekdays();
-
-        case ABBREVIATED:
-        case NARROW:
-            return dfs.getShortWeekdays();
-
-        default:
-            throw new IllegalArgumentException("Unsupported width argument value");
-        }
-    }
-
-    /**
-     * Sets weekday strings. For example: "Sunday", "Monday", etc.
-     * @param newWeekdays The new weekday strings.
-     * @param context     The formatting context, FORMAT or STANDALONE.
-     * @param width       The width of the strings,
-     *                    either WIDE, ABBREVIATED, or NARROW.
-     * @stable ICU 3.8
-     */
-    public void setWeekdays(String[] newWeekdays, int context, int width) {
-        // JDK does not support context / narrow weekdays
-        switch (width) {
-        case WIDE:
-            dfs.setWeekdays(newWeekdays);
-            break;
-
-        case ABBREVIATED:
-        case NARROW:
-            dfs.setShortWeekdays(newWeekdays);
-            break;
-
-        default:
-            throw new IllegalArgumentException("Unsupported width argument value");
-        }
-    }
-
-    /**
-     * Sets weekday strings. For example: "Sunday", "Monday", etc.
-     * @param newWeekdays the new weekday strings. The array should
-     * be indexed by <code>Calendar.SUNDAY</code>,
-     * <code>Calendar.MONDAY</code>, etc.
-     * @stable ICU 2.0
-     */
-    public void setWeekdays(String[] newWeekdays) {
-        dfs.setWeekdays(newWeekdays);
-    }
-
-    /**
-     * Returns short weekday strings. For example: "Sun", "Mon", etc.
-     * @return the short weekday strings. Use <code>Calendar.SUNDAY</code>,
-     * <code>Calendar.MONDAY</code>, etc. to index the result array.
-     * @stable ICU 2.0
-     */
-    public String[] getShortWeekdays() {
-        return dfs.getShortWeekdays();
-    }
-
-    /**
-     * Sets short weekday strings. For example: "Sun", "Mon", etc.
-     * @param newShortWeekdays the new short weekday strings. The array should
-     * be indexed by <code>Calendar.SUNDAY</code>,
-     * <code>Calendar.MONDAY</code>, etc.
-     * @stable ICU 2.0
-     */
-    public void setShortWeekdays(String[] newShortWeekdays) {
-        dfs.setShortWeekdays(newShortWeekdays);
-    }
-
-//    /**
-//     * {@icu} Returns quarter strings. For example: "1st Quarter", "2nd Quarter", etc.
-//     * @param context    The quarter context, FORMAT or STANDALONE.
-//     * @param width      The width or the returned quarter string,
-//     *                   either WIDE or ABBREVIATED. There are no NARROW quarters.
-//     * @return the quarter strings.
-//     * @stable ICU 3.6
-//     */
-//    public String[] getQuarters(int context, int width) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets quarter strings. For example: "1st Quarter", "2nd Quarter", etc.
-//     * @param newQuarters the new quarter strings.
-//     * @param context    The formatting context, FORMAT or STANDALONE.
-//     * @param width      The width of the quarter string,
-//     *                   either WIDE or ABBREVIATED. There are no NARROW quarters.
-//     * @stable ICU 3.8
-//     */
-//    public void setQuarters(String[] newQuarters, int context, int width) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Returns am/pm strings. For example: "AM" and "PM".
-     * @return the weekday strings.
-     * @stable ICU 2.0
-     */
-    public String[] getAmPmStrings() {
-        return dfs.getAmPmStrings();
-    }
-
-    /**
-     * Sets am/pm strings. For example: "AM" and "PM".
-     * @param newAmpms the new ampm strings.
-     * @stable ICU 2.0
-     */
-    public void setAmPmStrings(String[] newAmpms) {
-        dfs.setAmPmStrings(newAmpms);
-    }
-
-    /**
-     * Returns timezone strings.
-     * @return the timezone strings.
-     * @stable ICU 2.0
-     */
-    public String[][] getZoneStrings() {
-        return dfs.getZoneStrings();
-    }
-
-    /**
-     * Sets timezone strings.
-     * @param newZoneStrings the new timezone strings.
-     * @stable ICU 2.0
-     */
-    public void setZoneStrings(String[][] newZoneStrings) {
-        dfs.setZoneStrings(newZoneStrings);
-    }
-
-    /**
-     * Returns localized date-time pattern characters. For example: 'u', 't', etc.
-     *
-     * <p>Note: ICU no longer provides localized date-time pattern characters for a locale
-     * starting ICU 3.8.  This method returns the non-localized date-time pattern
-     * characters unless user defined localized data is set by setLocalPatternChars.
-     * @return the localized date-time pattern characters.
-     * @stable ICU 2.0
-     */
-    public String getLocalPatternChars() {
-        return dfs.getLocalPatternChars();
-    }
-
-    /**
-     * Sets localized date-time pattern characters. For example: 'u', 't', etc.
-     * @param newLocalPatternChars the new localized date-time
-     * pattern characters.
-     * @stable ICU 2.0
-     */
-    public void setLocalPatternChars(String newLocalPatternChars) {
-        dfs.setLocalPatternChars(newLocalPatternChars);
-    }
-
-    /**
-     * Overrides clone.
-     * @stable ICU 2.0
-     */
-    public Object clone()
-    {
-        return new DateFormatSymbols((java.text.DateFormatSymbols)dfs.clone());
-    }
-
-    /**
-     * Override hashCode.
-     * Generates a hash code for the DateFormatSymbols object.
-     * @stable ICU 2.0
-     */
-    public int hashCode() {
-        return dfs.hashCode();
-    }
-
-    /**
-     * Overrides equals.
-     * @stable ICU 2.0
-     */
-    public boolean equals(Object obj)
-    {
-        try {
-            return dfs.equals(((DateFormatSymbols)obj).dfs);
-        }
-        catch (Exception e) {
-            return false;
-        }
-    }
-
-    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-//    /**
-//     * Returns the {@link DateFormatSymbols} object that should be used to format a
-//     * calendar system's dates in the given locale.
-//     * <p>
-//     * <b>Subclassing:</b><br>
-//     * When creating a new Calendar subclass, you must create the
-//     * {@link ResourceBundle ResourceBundle}
-//     * containing its {@link DateFormatSymbols DateFormatSymbols} in a specific place.
-//     * The resource bundle name is based on the calendar's fully-specified
-//     * class name, with ".resources" inserted at the end of the package name
-//     * (just before the class name) and "Symbols" appended to the end.
-//     * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar"
-//     * is "com.ibm.icu.impl.data.HebrewCalendarSymbols".
-//     * <p>
-//     * Within the ResourceBundle, this method searches for five keys:
-//     * <ul>
-//     * <li><b>DayNames</b> -
-//     *      An array of strings corresponding to each possible
-//     *      value of the <code>DAY_OF_WEEK</code> field.  Even though
-//     *      <code>DAY_OF_WEEK</code> starts with <code>SUNDAY</code> = 1,
-//     *      This array is 0-based; the name for Sunday goes in the
-//     *      first position, at index 0.  If this key is not found
-//     *      in the bundle, the day names are inherited from the
-//     *      default <code>DateFormatSymbols</code> for the requested locale.
-//     *
-//     * <li><b>DayAbbreviations</b> -
-//     *      An array of abbreviated day names corresponding
-//     *      to the values in the "DayNames" array.  If this key
-//     *      is not found in the resource bundle, the "DayNames"
-//     *      values are used instead.  If neither key is found,
-//     *      the day abbreviations are inherited from the default
-//     *      <code>DateFormatSymbols</code> for the locale.
-//     *
-//     * <li><b>MonthNames</b> -
-//     *      An array of strings corresponding to each possible
-//     *      value of the <code>MONTH</code> field.  If this key is not found
-//     *      in the bundle, the month names are inherited from the
-//     *      default <code>DateFormatSymbols</code> for the requested locale.
-//     *
-//     * <li><b>MonthAbbreviations</b> -
-//     *      An array of abbreviated day names corresponding
-//     *      to the values in the "MonthNames" array.  If this key
-//     *      is not found in the resource bundle, the "MonthNames"
-//     *      values are used instead.  If neither key is found,
-//     *      the day abbreviations are inherited from the default
-//     *      <code>DateFormatSymbols</code> for the locale.
-//     *
-//     * <li><b>Eras</b> -
-//     *      An array of strings corresponding to each possible
-//     *      value of the <code>ERA</code> field.  If this key is not found
-//     *      in the bundle, the era names are inherited from the
-//     *      default <code>DateFormatSymbols</code> for the requested locale.
-//     * </ul>
-//     * <p>
-//     * @param cal       The calendar system whose date format symbols are desired.
-//     * @param locale    The locale whose symbols are desired.
-//     *
-//     * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale)
-//     * @stable ICU 2.0
-//     */
-//    public DateFormatSymbols(Calendar cal, Locale locale) {
-//        throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Returns the {@link DateFormatSymbols} object that should be used to format a
-//     * calendar system's dates in the given locale.
-//     * <p>
-//     * <b>Subclassing:</b><br>
-//     * When creating a new Calendar subclass, you must create the
-//     * {@link ResourceBundle ResourceBundle}
-//     * containing its {@link DateFormatSymbols DateFormatSymbols} in a specific place.
-//     * The resource bundle name is based on the calendar's fully-specified
-//     * class name, with ".resources" inserted at the end of the package name
-//     * (just before the class name) and "Symbols" appended to the end.
-//     * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar"
-//     * is "com.ibm.icu.impl.data.HebrewCalendarSymbols".
-//     * <p>
-//     * Within the ResourceBundle, this method searches for five keys:
-//     * <ul>
-//     * <li><b>DayNames</b> -
-//     *      An array of strings corresponding to each possible
-//     *      value of the <code>DAY_OF_WEEK</code> field.  Even though
-//     *      <code>DAY_OF_WEEK</code> starts with <code>SUNDAY</code> = 1,
-//     *      This array is 0-based; the name for Sunday goes in the
-//     *      first position, at index 0.  If this key is not found
-//     *      in the bundle, the day names are inherited from the
-//     *      default <code>DateFormatSymbols</code> for the requested locale.
-//     *
-//     * <li><b>DayAbbreviations</b> -
-//     *      An array of abbreviated day names corresponding
-//     *      to the values in the "DayNames" array.  If this key
-//     *      is not found in the resource bundle, the "DayNames"
-//     *      values are used instead.  If neither key is found,
-//     *      the day abbreviations are inherited from the default
-//     *      <code>DateFormatSymbols</code> for the locale.
-//     *
-//     * <li><b>MonthNames</b> -
-//     *      An array of strings corresponding to each possible
-//     *      value of the <code>MONTH</code> field.  If this key is not found
-//     *      in the bundle, the month names are inherited from the
-//     *      default <code>DateFormatSymbols</code> for the requested locale.
-//     *
-//     * <li><b>MonthAbbreviations</b> -
-//     *      An array of abbreviated day names corresponding
-//     *      to the values in the "MonthNames" array.  If this key
-//     *      is not found in the resource bundle, the "MonthNames"
-//     *      values are used instead.  If neither key is found,
-//     *      the day abbreviations are inherited from the default
-//     *      <code>DateFormatSymbols</code> for the locale.
-//     *
-//     * <li><b>Eras</b> -
-//     *      An array of strings corresponding to each possible
-//     *      value of the <code>ERA</code> field.  If this key is not found
-//     *      in the bundle, the era names are inherited from the
-//     *      default <code>DateFormatSymbols</code> for the requested locale.
-//     * </ul>
-//     * <p>
-//     * @param cal       The calendar system whose date format symbols are desired.
-//     * @param locale    The ulocale whose symbols are desired.
-//     *
-//     * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale)
-//     * @stable ICU 3.2
-//     */
-//    public DateFormatSymbols(Calendar cal, ULocale locale) {
-//        throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Variant of DateFormatSymbols(Calendar, Locale) that takes the Calendar class
-//     * instead of a Calendar instance.
-//     * @see #DateFormatSymbols(Calendar, Locale)
-//     * @stable ICU 2.2
-//     */
-//    public DateFormatSymbols(Class<? extends Calendar> calendarClass, Locale locale) {
-//        throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Variant of DateFormatSymbols(Calendar, ULocale) that takes the Calendar class
-//     * instead of a Calendar instance.
-//     * @see #DateFormatSymbols(Calendar, Locale)
-//     * @stable ICU 3.2
-//     */
-//    public DateFormatSymbols(Class<? extends Calendar> calendarClass, ULocale locale) {
-//        throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Fetches a custom calendar's DateFormatSymbols out of the given resource
-//     * bundle.  Symbols that are not overridden are inherited from the
-//     * default DateFormatSymbols for the locale.
-//     * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale)
-//     * @stable ICU 2.0
-//     */
-//    public DateFormatSymbols(ResourceBundle bundle, Locale locale) {
-//        throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Fetches a custom calendar's DateFormatSymbols out of the given resource
-//     * bundle.  Symbols that are not overridden are inherited from the
-//     * default DateFormatSymbols for the locale.
-//     * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale)
-//     * @stable ICU 3.2
-//     */
-//    public DateFormatSymbols(ResourceBundle bundle, ULocale locale) {
-//        throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Finds the ResourceBundle containing the date format information for
-//     * a specified calendar subclass in a given locale.
-//     * <p>
-//     * The resource bundle name is based on the calendar's fully-specified
-//     * class name, with ".resources" inserted at the end of the package name
-//     * (just before the class name) and "Symbols" appended to the end.
-//     * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar"
-//     * is "com.ibm.icu.impl.data.HebrewCalendarSymbols".
-//     * <p>
-//     * <b>Note:</b>Because of the structural changes in the ICU locale bundle,
-//     * this API no longer works as described.  This method always returns null.
-//     * @deprecated ICU 4.0
-//     */
-//    // This API was formerly @stable ICU 2.0
-//    static public ResourceBundle getDateFormatBundle(Class<? extends Calendar> calendarClass,
-//                                                     Locale locale) throws MissingResourceException {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Finds the ResourceBundle containing the date format information for
-//     * a specified calendar subclass in a given locale.
-//     * <p>
-//     * The resource bundle name is based on the calendar's fully-specified
-//     * class name, with ".resources" inserted at the end of the package name
-//     * (just before the class name) and "Symbols" appended to the end.
-//     * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar"
-//     * is "com.ibm.icu.impl.data.HebrewCalendarSymbols".
-//     * <p>
-//     * <b>Note:</b>Because of the structural changes in the ICU locale bundle,
-//     * this API no longer works as described.  This method always returns null.
-//     * @deprecated ICU 4.0
-//     */
-//    // This API was formerly @stable ICU 3.2
-//    static public ResourceBundle getDateFormatBundle(Class<? extends Calendar> calendarClass,
-//                                                     ULocale locale) throws MissingResourceException {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Variant of getDateFormatBundle(java.lang.Class, java.util.Locale) that takes
-//     * a Calendar instance instead of a Calendar class.
-//     * <p>
-//     * <b>Note:</b>Because of the structural changes in the ICU locale bundle,
-//     * this API no longer works as described.  This method always returns null.
-//     * @see #getDateFormatBundle(java.lang.Class, java.util.Locale)
-//     * @deprecated ICU 4.0
-//     */
-//    // This API was formerly @stable ICU 2.2
-//    public static ResourceBundle getDateFormatBundle(Calendar cal, Locale locale) throws MissingResourceException {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Variant of getDateFormatBundle(java.lang.Class, java.util.Locale) that takes
-//     * a Calendar instance instead of a Calendar class.
-//     * <p>
-//     * <b>Note:</b>Because of the structural changes in the ICU locale bundle,
-//     * this API no longer works as described.  This method always returns null.
-//     * @see #getDateFormatBundle(java.lang.Class, java.util.Locale)
-//     * @deprecated ICU 4.0
-//     */
-//    // This API was formerly @stable ICU 3.2
-//    public static ResourceBundle getDateFormatBundle(Calendar cal, ULocale locale) throws MissingResourceException {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Returns the locale that was used to create this object, or null.
-//     * This may may differ from the locale requested at the time of
-//     * this object's creation.  For example, if an object is created
-//     * for locale <tt>en_US_CALIFORNIA</tt>, the actual data may be
-//     * drawn from <tt>en</tt> (the <i>actual</i> locale), and
-//     * <tt>en_US</tt> may be the most specific locale that exists (the
-//     * <i>valid</i> locale).
-//     *
-//     * <p>Note: This method will be implemented in ICU 3.0; ICU 2.8
-//     * contains a partial preview implementation.  The * <i>actual</i>
-//     * locale is returned correctly, but the <i>valid</i> locale is
-//     * not, in most cases.
-//     * @param type type of information requested, either {@link
-//     * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link
-//     * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}.
-//     * @return the information specified by <i>type</i>, or null if
-//     * this object was not constructed from locale data.
-//     * @see com.ibm.icu.util.ULocale
-//     * @see com.ibm.icu.util.ULocale#VALID_LOCALE
-//     * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
-//     * @draft ICU 2.8 (retain)
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public final ULocale getLocale(ULocale.Type type) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormat.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormat.java
deleted file mode 100644
index 57ee6f8..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormat.java
+++ /dev/null
@@ -1,1779 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 1996-2012, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.text;
-
-import java.math.BigInteger;
-import java.text.AttributedCharacterIterator;
-import java.text.AttributedCharacterIterator.Attribute;
-import java.text.AttributedString;
-import java.text.CharacterIterator;
-import java.text.FieldPosition;
-import java.text.ParsePosition;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import com.ibm.icu.math.BigDecimal;
-import com.ibm.icu.util.Currency;
-import com.ibm.icu.util.ULocale;
-import com.ibm.icu.util.ULocale.Category;
-
-/**
- * {@icuenhanced java.text.DecimalFormat}.{@icu _usage_}
- *
- * <code>DecimalFormat</code> is a concrete subclass of {@link NumberFormat} that formats
- * decimal numbers. It has a variety of features designed to make it possible to parse and
- * format numbers in any locale, including support for Western, Arabic, or Indic digits.
- * It also supports different flavors of numbers, including integers ("123"), fixed-point
- * numbers ("123.4"), scientific notation ("1.23E4"), percentages ("12%"), and currency
- * amounts ("$123.00", "USD123.00", "123.00 US dollars").  All of these flavors can be
- * easily localized.
- *
- * <p>To obtain a {@link NumberFormat} for a specific locale (including the default
- * locale) call one of <code>NumberFormat</code>'s factory methods such as {@link
- * NumberFormat#getInstance}. Do not call the <code>DecimalFormat</code> constructors
- * directly, unless you know what you are doing, since the {@link NumberFormat} factory
- * methods may return subclasses other than <code>DecimalFormat</code>. If you need to
- * customize the format object, do something like this:
- *
- * <blockquote><pre>
- * NumberFormat f = NumberFormat.getInstance(loc);
- * if (f instanceof DecimalFormat) {
- *     ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
- * }</pre></blockquote>
- *
- * <p><strong>Example Usage</strong>
- *
- * Print out a number using the localized number, currency, and percent
- * format for each locale.
- *
- * <blockquote><pre>
- * Locale[] locales = NumberFormat.getAvailableLocales();
- * double myNumber = -1234.56;
- * NumberFormat format;
- * for (int j=0; j<3; ++j) {
- *     System.out.println("FORMAT");
- *     for (int i = 0; i < locales.length; ++i) {
- *         if (locales[i].getCountry().length() == 0) {
- *            // Skip language-only locales
- *            continue;
- *         }
- *         System.out.print(locales[i].getDisplayName());
- *         switch (j) {
- *         case 0:
- *             format = NumberFormat.getInstance(locales[i]); break;
- *         case 1:
- *             format = NumberFormat.getCurrencyInstance(locales[i]); break;
- *         default:
- *             format = NumberFormat.getPercentInstance(locales[i]); break;
- *         }
- *         try {
- *             // Assume format is a DecimalFormat
- *             System.out.print(": " + ((DecimalFormat) format).toPattern()
- *                              + " -> " + form.format(myNumber));
- *         } catch (Exception e) {}
- *         try {
- *             System.out.println(" -> " + format.parse(form.format(myNumber)));
- *         } catch (ParseException e) {}
- *     }
- * }</pre></blockquote>
- *
- * <p>Another example use getInstance(style).<br/>
- * Print out a number using the localized number, currency, percent,
- * scientific, integer, iso currency, and plural currency format for each locale.
- *
- * <blockquote><pre>
- * ULocale locale = new ULocale("en_US");
- * double myNumber = 1234.56;
- * for (int j=NumberFormat.NUMBERSTYLE; j<=NumberFormat.PLURALCURRENCYSTYLE; ++j) {
- *     NumberFormat format = NumberFormat.getInstance(locale, j);
- *     try {
- *         // Assume format is a DecimalFormat
- *         System.out.print(": " + ((DecimalFormat) format).toPattern()
- *                          + " -> " + form.format(myNumber));
- *     } catch (Exception e) {}
- *     try {
- *         System.out.println(" -> " + format.parse(form.format(myNumber)));
- *     } catch (ParseException e) {}
- * }</pre></blockquote>
- *
- * <h4>Patterns</h4>
- *
- * <p>A <code>DecimalFormat</code> consists of a <em>pattern</em> and a set of
- * <em>symbols</em>.  The pattern may be set directly using {@link #applyPattern}, or
- * indirectly using other API methods which manipulate aspects of the pattern, such as the
- * minimum number of integer digits.  The symbols are stored in a {@link
- * DecimalFormatSymbols} object.  When using the {@link NumberFormat} factory methods, the
- * pattern and symbols are read from ICU's locale data.
- *
- * <h4>Special Pattern Characters</h4>
- *
- * <p>Many characters in a pattern are taken literally; they are matched during parsing
- * and output unchanged during formatting.  Special characters, on the other hand, stand
- * for other characters, strings, or classes of characters.  For example, the '#'
- * character is replaced by a localized digit.  Often the replacement character is the
- * same as the pattern character; in the U.S. locale, the ',' grouping character is
- * replaced by ','.  However, the replacement is still happening, and if the symbols are
- * modified, the grouping character changes.  Some special characters affect the behavior
- * of the formatter by their presence; for example, if the percent character is seen, then
- * the value is multiplied by 100 before being displayed.
- *
- * <p>To insert a special character in a pattern as a literal, that is, without any
- * special meaning, the character must be quoted.  There are some exceptions to this which
- * are noted below.
- *
- * <p>The characters listed here are used in non-localized patterns.  Localized patterns
- * use the corresponding characters taken from this formatter's {@link
- * DecimalFormatSymbols} object instead, and these characters lose their special status.
- * Two exceptions are the currency sign and quote, which are not localized.
- *
- * <blockquote>
- * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol,
- *  location, localized, and meaning.">
- *   <tr bgcolor="#ccccff">
- *     <th align=left>Symbol
- *     <th align=left>Location
- *     <th align=left>Localized?
- *     <th align=left>Meaning
- *   <tr valign=top>
- *     <td><code>0</code>
- *     <td>Number
- *     <td>Yes
- *     <td>Digit
- *   <tr valign=top bgcolor="#eeeeff">
- *     <td><code>1-9</code>
- *     <td>Number
- *     <td>Yes
- *     <td>'1' through '9' indicate rounding.
- *   <tr valign=top>
- *     <td><code>@</code>
- *     <td>Number
- *     <td>No
- *     <td>Significant digit
- *   <tr valign=top bgcolor="#eeeeff">
- *     <td><code>#</code>
- *     <td>Number
- *     <td>Yes
- *     <td>Digit, zero shows as absent
- *   <tr valign=top>
- *     <td><code>.</code>
- *     <td>Number
- *     <td>Yes
- *     <td>Decimal separator or monetary decimal separator
- *   <tr valign=top bgcolor="#eeeeff">
- *     <td><code>-</code>
- *     <td>Number
- *     <td>Yes
- *     <td>Minus sign
- *   <tr valign=top>
- *     <td><code>,</code>
- *     <td>Number
- *     <td>Yes
- *     <td>Grouping separator
- *   <tr valign=top bgcolor="#eeeeff">
- *     <td><code>E</code>
- *     <td>Number
- *     <td>Yes
- *     <td>Separates mantissa and exponent in scientific notation.
- *         <em>Need not be quoted in prefix or suffix.</em>
- *   <tr valign=top>
- *     <td><code>+</code>
- *     <td>Exponent
- *     <td>Yes
- *     <td>Prefix positive exponents with localized plus sign.
- *         <em>Need not be quoted in prefix or suffix.</em>
- *   <tr valign=top bgcolor="#eeeeff">
- *     <td><code>;</code>
- *     <td>Subpattern boundary
- *     <td>Yes
- *     <td>Separates positive and negative subpatterns
- *   <tr valign=top>
- *     <td><code>%</code>
- *     <td>Prefix or suffix
- *     <td>Yes
- *     <td>Multiply by 100 and show as percentage
- *   <tr valign=top bgcolor="#eeeeff">
- *     <td><code>&#92;u2030</code>
- *     <td>Prefix or suffix
- *     <td>Yes
- *     <td>Multiply by 1000 and show as per mille
- *   <tr valign=top>
- *     <td><code>&#164;</code> (<code>&#92;u00A4</code>)
- *     <td>Prefix or suffix
- *     <td>No
- *     <td>Currency sign, replaced by currency symbol.  If
- *         doubled, replaced by international currency symbol.
- *         If tripled, replaced by currency plural names, for example,
- *         "US dollar" or "US dollars" for America.
- *         If present in a pattern, the monetary decimal separator
- *         is used instead of the decimal separator.
- *   <tr valign=top bgcolor="#eeeeff">
- *     <td><code>'</code>
- *     <td>Prefix or suffix
- *     <td>No
- *     <td>Used to quote special characters in a prefix or suffix,
- *         for example, <code>"'#'#"</code> formats 123 to
- *         <code>"#123"</code>.  To create a single quote
- *         itself, use two in a row: <code>"# o''clock"</code>.
- *   <tr valign=top>
- *     <td><code>*</code>
- *     <td>Prefix or suffix boundary
- *     <td>Yes
- *     <td>Pad escape, precedes pad character
- * </table>
- * </blockquote>
- *
- * <p>A <code>DecimalFormat</code> pattern contains a postive and negative subpattern, for
- * example, "#,##0.00;(#,##0.00)".  Each subpattern has a prefix, a numeric part, and a
- * suffix.  If there is no explicit negative subpattern, the negative subpattern is the
- * localized minus sign prefixed to the positive subpattern. That is, "0.00" alone is
- * equivalent to "0.00;-0.00".  If there is an explicit negative subpattern, it serves
- * only to specify the negative prefix and suffix; the number of digits, minimal digits,
- * and other characteristics are ignored in the negative subpattern. That means that
- * "#,##0.0#;(#)" has precisely the same result as "#,##0.0#;(#,##0.0#)".
- *
- * <p>The prefixes, suffixes, and various symbols used for infinity, digits, thousands
- * separators, decimal separators, etc. may be set to arbitrary values, and they will
- * appear properly during formatting.  However, care must be taken that the symbols and
- * strings do not conflict, or parsing will be unreliable.  For example, either the
- * positive and negative prefixes or the suffixes must be distinct for {@link #parse} to
- * be able to distinguish positive from negative values.  Another example is that the
- * decimal separator and thousands separator should be distinct characters, or parsing
- * will be impossible.
- *
- * <p>The <em>grouping separator</em> is a character that separates clusters of integer
- * digits to make large numbers more legible.  It commonly used for thousands, but in some
- * locales it separates ten-thousands.  The <em>grouping size</em> is the number of digits
- * between the grouping separators, such as 3 for "100,000,000" or 4 for "1 0000
- * 0000". There are actually two different grouping sizes: One used for the least
- * significant integer digits, the <em>primary grouping size</em>, and one used for all
- * others, the <em>secondary grouping size</em>.  In most locales these are the same, but
- * sometimes they are different. For example, if the primary grouping interval is 3, and
- * the secondary is 2, then this corresponds to the pattern "#,##,##0", and the number
- * 123456789 is formatted as "12,34,56,789".  If a pattern contains multiple grouping
- * separators, the interval between the last one and the end of the integer defines the
- * primary grouping size, and the interval between the last two defines the secondary
- * grouping size. All others are ignored, so "#,##,###,####" == "###,###,####" ==
- * "##,#,###,####".
- *
- * <p>Illegal patterns, such as "#.#.#" or "#.###,###", will cause
- * <code>DecimalFormat</code> to throw an {@link IllegalArgumentException} with a message
- * that describes the problem.
- *
- * <h4>Pattern BNF</h4>
- *
- * <pre>
- * pattern    := subpattern (';' subpattern)?
- * subpattern := prefix? number exponent? suffix?
- * number     := (integer ('.' fraction)?) | sigDigits
- * prefix     := '&#92;u0000'..'&#92;uFFFD' - specialCharacters
- * suffix     := '&#92;u0000'..'&#92;uFFFD' - specialCharacters
- * integer    := '#'* '0'* '0'
- * fraction   := '0'* '#'*
- * sigDigits  := '#'* '@' '@'* '#'*
- * exponent   := 'E' '+'? '0'* '0'
- * padSpec    := '*' padChar
- * padChar    := '&#92;u0000'..'&#92;uFFFD' - quote
- * &#32;
- * Notation:
- *   X*       0 or more instances of X
- *   X?       0 or 1 instances of X
- *   X|Y      either X or Y
- *   C..D     any character from C up to D, inclusive
- *   S-T      characters in S, except those in T
- * </pre>
- * The first subpattern is for positive numbers. The second (optional)
- * subpattern is for negative numbers.
- *
- * <p>Not indicated in the BNF syntax above:
- *
- * <ul>
- *
- * <li>The grouping separator ',' can occur inside the integer and sigDigits
- * elements, between any two pattern characters of that element, as long as the integer or
- * sigDigits element is not followed by the exponent element.
- *
- * <li>Two grouping intervals are recognized: That between the decimal point and the first
- * grouping symbol, and that between the first and second grouping symbols. These
- * intervals are identical in most locales, but in some locales they differ. For example,
- * the pattern &quot;#,##,###&quot; formats the number 123456789 as
- * &quot;12,34,56,789&quot;.
- *
- * <li>The pad specifier <code>padSpec</code> may appear before the prefix, after the
- * prefix, before the suffix, after the suffix, or not at all.
- *
- * <li>In place of '0', the digits '1' through '9' may be used to indicate a rounding
- * increment.
- *
- * </ul>
- *
- * <h4>Parsing</h4>
- *
- * <p><code>DecimalFormat</code> parses all Unicode characters that represent decimal
- * digits, as defined by {@link UCharacter#digit}.  In addition,
- * <code>DecimalFormat</code> also recognizes as digits the ten consecutive characters
- * starting with the localized zero digit defined in the {@link DecimalFormatSymbols}
- * object.  During formatting, the {@link DecimalFormatSymbols}-based digits are output.
- *
- * <p>During parsing, grouping separators are ignored.
- *
- * <p>For currency parsing, the formatter is able to parse every currency style formats no
- * matter which style the formatter is constructed with.  For example, a formatter
- * instance gotten from NumberFormat.getInstance(ULocale, NumberFormat.CURRENCYSTYLE) can
- * parse formats such as "USD1.00" and "3.00 US dollars".
- *
- * <p>If {@link #parse(String, ParsePosition)} fails to parse a string, it returns
- * <code>null</code> and leaves the parse position unchanged.  The convenience method
- * {@link #parse(String)} indicates parse failure by throwing a {@link
- * java.text.ParseException}.
- *
- * <h4>Formatting</h4>
- *
- * <p>Formatting is guided by several parameters, all of which can be specified either
- * using a pattern or using the API.  The following description applies to formats that do
- * not use <a href="#sci">scientific notation</a> or <a href="#sigdig">significant
- * digits</a>.
- *
- * <ul><li>If the number of actual integer digits exceeds the <em>maximum integer
- * digits</em>, then only the least significant digits are shown.  For example, 1997 is
- * formatted as "97" if the maximum integer digits is set to 2.
- *
- * <li>If the number of actual integer digits is less than the <em>minimum integer
- * digits</em>, then leading zeros are added.  For example, 1997 is formatted as "01997"
- * if the minimum integer digits is set to 5.
- *
- * <li>If the number of actual fraction digits exceeds the <em>maximum fraction
- * digits</em>, then half-even rounding it performed to the maximum fraction digits.  For
- * example, 0.125 is formatted as "0.12" if the maximum fraction digits is 2.  This
- * behavior can be changed by specifying a rounding increment and a rounding mode.
- *
- * <li>If the number of actual fraction digits is less than the <em>minimum fraction
- * digits</em>, then trailing zeros are added.  For example, 0.125 is formatted as
- * "0.1250" if the mimimum fraction digits is set to 4.
- *
- * <li>Trailing fractional zeros are not displayed if they occur <em>j</em> positions
- * after the decimal, where <em>j</em> is less than the maximum fraction digits. For
- * example, 0.10004 is formatted as "0.1" if the maximum fraction digits is four or less.
- * </ul>
- *
- * <p><strong>Special Values</strong>
- *
- * <p><code>NaN</code> is represented as a single character, typically
- * <code>&#92;uFFFD</code>.  This character is determined by the {@link
- * DecimalFormatSymbols} object.  This is the only value for which the prefixes and
- * suffixes are not used.
- *
- * <p>Infinity is represented as a single character, typically <code>&#92;u221E</code>,
- * with the positive or negative prefixes and suffixes applied.  The infinity character is
- * determined by the {@link DecimalFormatSymbols} object.
- *
- * <a name="sci"><h4>Scientific Notation</h4></a>
- *
- * <p>Numbers in scientific notation are expressed as the product of a mantissa and a
- * power of ten, for example, 1234 can be expressed as 1.234 x 10<sup>3</sup>. The
- * mantissa is typically in the half-open interval [1.0, 10.0) or sometimes [0.0, 1.0),
- * but it need not be.  <code>DecimalFormat</code> supports arbitrary mantissas.
- * <code>DecimalFormat</code> can be instructed to use scientific notation through the API
- * or through the pattern.  In a pattern, the exponent character immediately followed by
- * one or more digit characters indicates scientific notation.  Example: "0.###E0" formats
- * the number 1234 as "1.234E3".
- *
- * <ul>
- *
- * <li>The number of digit characters after the exponent character gives the minimum
- * exponent digit count.  There is no maximum.  Negative exponents are formatted using the
- * localized minus sign, <em>not</em> the prefix and suffix from the pattern.  This allows
- * patterns such as "0.###E0 m/s".  To prefix positive exponents with a localized plus
- * sign, specify '+' between the exponent and the digits: "0.###E+0" will produce formats
- * "1E+1", "1E+0", "1E-1", etc.  (In localized patterns, use the localized plus sign
- * rather than '+'.)
- *
- * <li>The minimum number of integer digits is achieved by adjusting the exponent.
- * Example: 0.00123 formatted with "00.###E0" yields "12.3E-4".  This only happens if
- * there is no maximum number of integer digits.  If there is a maximum, then the minimum
- * number of integer digits is fixed at one.
- *
- * <li>The maximum number of integer digits, if present, specifies the exponent grouping.
- * The most common use of this is to generate <em>engineering notation</em>, in which the
- * exponent is a multiple of three, e.g., "##0.###E0".  The number 12345 is formatted
- * using "##0.####E0" as "12.345E3".
- *
- * <li>When using scientific notation, the formatter controls the digit counts using
- * significant digits logic.  The maximum number of significant digits limits the total
- * number of integer and fraction digits that will be shown in the mantissa; it does not
- * affect parsing.  For example, 12345 formatted with "##0.##E0" is "12.3E3".  See the
- * section on significant digits for more details.
- *
- * <li>The number of significant digits shown is determined as follows: If
- * areSignificantDigitsUsed() returns false, then the minimum number of significant digits
- * shown is one, and the maximum number of significant digits shown is the sum of the
- * <em>minimum integer</em> and <em>maximum fraction</em> digits, and is unaffected by the
- * maximum integer digits.  If this sum is zero, then all significant digits are shown.
- * If areSignificantDigitsUsed() returns true, then the significant digit counts are
- * specified by getMinimumSignificantDigits() and getMaximumSignificantDigits().  In this
- * case, the number of integer digits is fixed at one, and there is no exponent grouping.
- *
- * <li>Exponential patterns may not contain grouping separators.
- *
- * </ul>
- *
- * <a name="sigdig"><h4>Significant Digits</h4></a>
- *
- * <code>DecimalFormat</code> has two ways of controlling how many digits are shows: (a)
- * significant digits counts, or (b) integer and fraction digit counts.  Integer and
- * fraction digit counts are described above.  When a formatter is using significant
- * digits counts, the number of integer and fraction digits is not specified directly, and
- * the formatter settings for these counts are ignored.  Instead, the formatter uses
- * however many integer and fraction digits are required to display the specified number
- * of significant digits.  Examples:
- *
- * <blockquote>
- * <table border=0 cellspacing=3 cellpadding=0>
- *   <tr bgcolor="#ccccff">
- *     <th align=left>Pattern
- *     <th align=left>Minimum significant digits
- *     <th align=left>Maximum significant digits
- *     <th align=left>Number
- *     <th align=left>Output of format()
- *   <tr valign=top>
- *     <td><code>@@@</code>
- *     <td>3
- *     <td>3
- *     <td>12345
- *     <td><code>12300</code>
- *   <tr valign=top bgcolor="#eeeeff">
- *     <td><code>@@@</code>
- *     <td>3
- *     <td>3
- *     <td>0.12345
- *     <td><code>0.123</code>
- *   <tr valign=top>
- *     <td><code>@@##</code>
- *     <td>2
- *     <td>4
- *     <td>3.14159
- *     <td><code>3.142</code>
- *   <tr valign=top bgcolor="#eeeeff">
- *     <td><code>@@##</code>
- *     <td>2
- *     <td>4
- *     <td>1.23004
- *     <td><code>1.23</code>
- * </table>
- * </blockquote>
- *
- * <ul>
- *
- * <li>Significant digit counts may be expressed using patterns that specify a minimum and
- * maximum number of significant digits.  These are indicated by the <code>'@'</code> and
- * <code>'#'</code> characters.  The minimum number of significant digits is the number of
- * <code>'@'</code> characters.  The maximum number of significant digits is the number of
- * <code>'@'</code> characters plus the number of <code>'#'</code> characters following on
- * the right.  For example, the pattern <code>"@@@"</code> indicates exactly 3 significant
- * digits.  The pattern <code>"@##"</code> indicates from 1 to 3 significant digits.
- * Trailing zero digits to the right of the decimal separator are suppressed after the
- * minimum number of significant digits have been shown.  For example, the pattern
- * <code>"@##"</code> formats the number 0.1203 as <code>"0.12"</code>.
- *
- * <li>If a pattern uses significant digits, it may not contain a decimal separator, nor
- * the <code>'0'</code> pattern character.  Patterns such as <code>"@00"</code> or
- * <code>"@.###"</code> are disallowed.
- *
- * <li>Any number of <code>'#'</code> characters may be prepended to the left of the
- * leftmost <code>'@'</code> character.  These have no effect on the minimum and maximum
- * significant digits counts, but may be used to position grouping separators.  For
- * example, <code>"#,#@#"</code> indicates a minimum of one significant digits, a maximum
- * of two significant digits, and a grouping size of three.
- *
- * <li>In order to enable significant digits formatting, use a pattern containing the
- * <code>'@'</code> pattern character.  Alternatively, call {@link
- * #setSignificantDigitsUsed setSignificantDigitsUsed(true)}.
- *
- * <li>In order to disable significant digits formatting, use a pattern that does not
- * contain the <code>'@'</code> pattern character. Alternatively, call {@link
- * #setSignificantDigitsUsed setSignificantDigitsUsed(false)}.
- *
- * <li>The number of significant digits has no effect on parsing.
- *
- * <li>Significant digits may be used together with exponential notation. Such patterns
- * are equivalent to a normal exponential pattern with a minimum and maximum integer digit
- * count of one, a minimum fraction digit count of <code>getMinimumSignificantDigits() -
- * 1</code>, and a maximum fraction digit count of <code>getMaximumSignificantDigits() -
- * 1</code>. For example, the pattern <code>"@@###E0"</code> is equivalent to
- * <code>"0.0###E0"</code>.
- *
- * <li>If signficant digits are in use, then the integer and fraction digit counts, as set
- * via the API, are ignored.  If significant digits are not in use, then the signficant
- * digit counts, as set via the API, are ignored.
- *
- * </ul>
- *
- * <h4>Padding</h4>
- *
- * <p><code>DecimalFormat</code> supports padding the result of {@link #format} to a
- * specific width.  Padding may be specified either through the API or through the pattern
- * syntax.  In a pattern the pad escape character, followed by a single pad character,
- * causes padding to be parsed and formatted.  The pad escape character is '*' in
- * unlocalized patterns, and can be localized using {@link
- * DecimalFormatSymbols#setPadEscape}.  For example, <code>"$*x#,##0.00"</code> formats
- * 123 to <code>"$xx123.00"</code>, and 1234 to <code>"$1,234.00"</code>.
- *
- * <ul>
- *
- * <li>When padding is in effect, the width of the positive subpattern, including prefix
- * and suffix, determines the format width.  For example, in the pattern <code>"* #0
- * o''clock"</code>, the format width is 10.
- *
- * <li>The width is counted in 16-bit code units (Java <code>char</code>s).
- *
- * <li>Some parameters which usually do not matter have meaning when padding is used,
- * because the pattern width is significant with padding.  In the pattern "*
- * ##,##,#,##0.##", the format width is 14.  The initial characters "##,##," do not affect
- * the grouping size or maximum integer digits, but they do affect the format width.
- *
- * <li>Padding may be inserted at one of four locations: before the prefix, after the
- * prefix, before the suffix, or after the suffix.  If padding is specified in any other
- * location, {@link #applyPattern} throws an {@link IllegalArgumentException}.  If there
- * is no prefix, before the prefix and after the prefix are equivalent, likewise for the
- * suffix.
- *
- * <li>When specified in a pattern, the 16-bit <code>char</code> immediately following the
- * pad escape is the pad character. This may be any character, including a special pattern
- * character. That is, the pad escape <em>escapes</em> the following character. If there
- * is no character after the pad escape, then the pattern is illegal.
- *
- * </ul>
- *
- * <p>
- * <strong>Rounding</strong>
- *
- * <p><code>DecimalFormat</code> supports rounding to a specific increment.  For example,
- * 1230 rounded to the nearest 50 is 1250.  1.234 rounded to the nearest 0.65 is 1.3.  The
- * rounding increment may be specified through the API or in a pattern.  To specify a
- * rounding increment in a pattern, include the increment in the pattern itself.  "#,#50"
- * specifies a rounding increment of 50.  "#,##0.05" specifies a rounding increment of
- * 0.05.
- *
- * <ul>
- *
- * <li>Rounding only affects the string produced by formatting.  It does not affect
- * parsing or change any numerical values.
- *
- * <li>A <em>rounding mode</em> determines how values are rounded; see the {@link
- * com.ibm.icu.math.BigDecimal} documentation for a description of the modes.  Rounding
- * increments specified in patterns use the default mode, {@link
- * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN}.
- *
- * <li>Some locales use rounding in their currency formats to reflect the smallest
- * currency denomination.
- *
- * <li>In a pattern, digits '1' through '9' specify rounding, but otherwise behave
- * identically to digit '0'.
- *
- * </ul>
- *
- * <h4>Synchronization</h4>
- *
- * <p><code>DecimalFormat</code> objects are not synchronized.  Multiple threads should
- * not access one formatter concurrently.
- *
- * @see          java.text.Format
- * @see          NumberFormat
- * @author       Mark Davis
- * @author       Alan Liu
- * @stable ICU 2.0
- */
-public class DecimalFormat extends NumberFormat {
-
-    private static final long serialVersionUID = 1L;
-    /**
-     * @internal
-     * @param delegate the NumberFormat to which to delegate
-     */
-    public DecimalFormat(java.text.DecimalFormat delegate) {
-        super(delegate);
-    }
-
-    /**
-     * Creates a DecimalFormat using the default pattern and symbols for the default
-     * locale. This is a convenient way to obtain a DecimalFormat when
-     * internationalization is not the main concern.
-     *
-     * <p>To obtain standard formats for a given locale, use the factory methods on
-     * NumberFormat such as getNumberInstance.  These factories will return the most
-     * appropriate sub-class of NumberFormat for a given locale.
-     *
-     * @see NumberFormat#getInstance
-     * @see NumberFormat#getNumberInstance
-     * @see NumberFormat#getCurrencyInstance
-     * @see NumberFormat#getPercentInstance
-     * @stable ICU 2.0
-     */
-    public DecimalFormat() {
-        // There is no way to construct java.text.DecimalFormat with an
-        // explicit Locale.
-        this(new java.text.DecimalFormat());
-
-        if (!ULocale.getDefault(Category.FORMAT).toLocale().equals(Locale.getDefault())) {
-            // On Java 6 or older JRE, ULocale's FORMAT default might be different
-            // from the locale used for constructing java.text.DecimalFormat
-            java.text.NumberFormat jdkNfmt = java.text.NumberFormat.getInstance(ULocale.getDefault(Category.FORMAT).toLocale());
-            if (jdkNfmt instanceof java.text.DecimalFormat) {
-                ((java.text.DecimalFormat)numberFormat).applyPattern(((java.text.DecimalFormat)jdkNfmt).toPattern());
-                ((java.text.DecimalFormat)numberFormat).setDecimalFormatSymbols(((java.text.DecimalFormat)jdkNfmt).getDecimalFormatSymbols());
-            }
-        }
-    }
-
-    /**
-     * Creates a DecimalFormat from the given pattern and the symbols for the default
-     * locale. This is a convenient way to obtain a DecimalFormat when
-     * internationalization is not the main concern.
-     *
-     * <p>To obtain standard formats for a given locale, use the factory methods on
-     * NumberFormat such as getNumberInstance.  These factories will return the most
-     * appropriate sub-class of NumberFormat for a given locale.
-     *
-     * @param pattern A non-localized pattern string.
-     * @throws IllegalArgumentException if the given pattern is invalid.
-     * @see NumberFormat#getInstance
-     * @see NumberFormat#getNumberInstance
-     * @see NumberFormat#getCurrencyInstance
-     * @see NumberFormat#getPercentInstance
-     * @stable ICU 2.0
-     */
-    public DecimalFormat(String pattern) {
-        this(new java.text.DecimalFormat(
-                pattern,
-                new java.text.DecimalFormatSymbols(ULocale.getDefault(Category.FORMAT).toLocale())));
-    }
-
-    /**
-     * Creates a DecimalFormat from the given pattern and symbols. Use this constructor
-     * when you need to completely customize the behavior of the format.
-     *
-     * <p>To obtain standard formats for a given locale, use the factory methods on
-     * NumberFormat such as getInstance or getCurrencyInstance. If you need only minor
-     * adjustments to a standard format, you can modify the format returned by a
-     * NumberFormat factory method.
-     *
-     * @param pattern a non-localized pattern string
-     * @param symbols the set of symbols to be used
-     * @exception IllegalArgumentException if the given pattern is invalid
-     * @see NumberFormat#getInstance
-     * @see NumberFormat#getNumberInstance
-     * @see NumberFormat#getCurrencyInstance
-     * @see NumberFormat#getPercentInstance
-     * @see DecimalFormatSymbols
-     * @stable ICU 2.0
-     */
-    public DecimalFormat(String pattern, DecimalFormatSymbols symbols) {
-        this(new java.text.DecimalFormat(pattern, symbols.dfs));
-    }
-
-//    /**
-//     * Creates a DecimalFormat from the given pattern, symbols, information used for
-//     * currency plural format, and format style. Use this constructor when you need to
-//     * completely customize the behavior of the format.
-//     *
-//     * <p>To obtain standard formats for a given locale, use the factory methods on
-//     * NumberFormat such as getInstance or getCurrencyInstance.
-//     *
-//     * <p>If you need only minor adjustments to a standard format, you can modify the
-//     * format returned by a NumberFormat factory method using the setters.
-//     *
-//     * <p>If you want to completely customize a decimal format, using your own
-//     * DecimalFormatSymbols (such as group separators) and your own information for
-//     * currency plural formatting (such as plural rule and currency plural patterns), you
-//     * can use this constructor.
-//     *
-//     * @param pattern a non-localized pattern string
-//     * @param symbols the set of symbols to be used
-//     * @param infoInput the information used for currency plural format, including
-//     * currency plural patterns and plural rules.
-//     * @param style the decimal formatting style, it is one of the following values:
-//     * NumberFormat.NUMBERSTYLE; NumberFormat.CURRENCYSTYLE; NumberFormat.PERCENTSTYLE;
-//     * NumberFormat.SCIENTIFICSTYLE; NumberFormat.INTEGERSTYLE;
-//     * NumberFormat.ISOCURRENCYSTYLE; NumberFormat.PLURALCURRENCYSTYLE;
-//     * @stable ICU 4.2
-//     */
-//    public DecimalFormat(String pattern, DecimalFormatSymbols symbols, CurrencyPluralInfo infoInput,
-//                         int style) {
-//        throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * {@inheritDoc}
-     * @stable ICU 2.0
-     */
-    public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition) {
-        return super.format(number, result, fieldPosition);
-    }
-
-    /**
-     * @stable ICU 2.0
-     */
-    // [Spark/CDL] Delegate to format_long_StringBuffer_FieldPosition_boolean
-    public StringBuffer format(long number, StringBuffer result, FieldPosition fieldPosition) {
-        return super.format(number, result, fieldPosition);
-    }
-
-    /**
-     * Formats a BigInteger number.
-     *
-     * @stable ICU 2.0
-     */
-    public StringBuffer format(BigInteger number, StringBuffer result,
-                               FieldPosition fieldPosition) {
-        return super.format(number, result, fieldPosition);
-    }
-
-    /**
-     * Formats a BigDecimal number.
-     *
-     * @stable ICU 2.0
-     */
-    public StringBuffer format(java.math.BigDecimal number, StringBuffer result,
-                               FieldPosition fieldPosition) {
-        return super.format(number, result, fieldPosition);
-    }
-
-    /**
-     * Formats a BigDecimal number.
-     *
-     * @stable ICU 2.0
-     */
-    public StringBuffer format(BigDecimal number, StringBuffer result,
-                               FieldPosition fieldPosition) {
-        return super.format(number, result, fieldPosition);
-    }
-
-    /**
-     * Parses the given string, returning a <code>Number</code> object to represent the
-     * parsed value. <code>Double</code> objects are returned to represent non-integral
-     * values which cannot be stored in a <code>BigDecimal</code>. These are
-     * <code>NaN</code>, infinity, -infinity, and -0.0. If {@link #isParseBigDecimal()} is
-     * false (the default), all other values are returned as <code>Long</code>,
-     * <code>BigInteger</code>, or <code>BigDecimal</code> values, in that order of
-     * preference. If {@link #isParseBigDecimal()} is true, all other values are returned
-     * as <code>BigDecimal</code> valuse. If the parse fails, null is returned.
-     *
-     * @param text the string to be parsed
-     * @param parsePosition defines the position where parsing is to begin, and upon
-     * return, the position where parsing left off. If the position has not changed upon
-     * return, then parsing failed.
-     * @return a <code>Number</code> object with the parsed value or
-     * <code>null</code> if the parse failed
-     * @stable ICU 2.0
-     */
-    public Number parse(String text, ParsePosition parsePosition) {
-        return super.parse(text, parsePosition);
-    }
-
-//    /**
-//     * Parses text from the given string as a CurrencyAmount. Unlike the parse() method,
-//     * this method will attempt to parse a generic currency name, searching for a match of
-//     * this object's locale's currency display names, or for a 3-letter ISO currency
-//     * code. This method will fail if this format is not a currency format, that is, if it
-//     * does not contain the currency pattern symbol (U+00A4) in its prefix or suffix.
-//     *
-//     * @param text the string to parse
-//     * @param pos input-output position; on input, the position within text to match; must
-//     *  have 0 <= pos.getIndex() < text.length(); on output, the position after the last
-//     *  matched character. If the parse fails, the position in unchanged upon output.
-//     * @return a CurrencyAmount, or null upon failure
-//     */
-//    CurrencyAmount parseCurrency(String text, ParsePosition pos) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Returns a copy of the decimal format symbols used by this format.
-     *
-     * @return desired DecimalFormatSymbols
-     * @see DecimalFormatSymbols
-     * @stable ICU 2.0
-     */
-    public DecimalFormatSymbols getDecimalFormatSymbols() {
-        return new DecimalFormatSymbols(((java.text.DecimalFormat)numberFormat).getDecimalFormatSymbols());
-    }
-
-    /**
-     * Sets the decimal format symbols used by this format. The format uses a copy of the
-     * provided symbols.
-     *
-     * @param newSymbols desired DecimalFormatSymbols
-     * @see DecimalFormatSymbols
-     * @stable ICU 2.0
-     */
-    public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
-        ((java.text.DecimalFormat)numberFormat).setDecimalFormatSymbols(newSymbols.dfs);
-    }
-
-    /**
-     * Returns the positive prefix.
-     *
-     * <p>Examples: +123, $123, sFr123
-     * @return the prefix
-     * @stable ICU 2.0
-     */
-    public String getPositivePrefix() {
-        return ((java.text.DecimalFormat)numberFormat).getPositivePrefix();
-    }
-
-    /**
-     * Sets the positive prefix.
-     *
-     * <p>Examples: +123, $123, sFr123
-     * @param newValue the prefix
-     * @stable ICU 2.0
-     */
-    public void setPositivePrefix(String newValue) {
-        ((java.text.DecimalFormat)numberFormat).setPositivePrefix(newValue);
-    }
-
-    /**
-     * Returns the negative prefix.
-     *
-     * <p>Examples: -123, ($123) (with negative suffix), sFr-123
-     *
-     * @return the prefix
-     * @stable ICU 2.0
-     */
-    public String getNegativePrefix() {
-        return ((java.text.DecimalFormat)numberFormat).getNegativePrefix();
-    }
-
-    /**
-     * Sets the negative prefix.
-     *
-     * <p>Examples: -123, ($123) (with negative suffix), sFr-123
-     * @param newValue the prefix
-     * @stable ICU 2.0
-     */
-    public void setNegativePrefix(String newValue) {
-        ((java.text.DecimalFormat)numberFormat).setNegativePrefix(newValue);
-    }
-
-    /**
-     * Returns the positive suffix.
-     *
-     * <p>Example: 123%
-     *
-     * @return the suffix
-     * @stable ICU 2.0
-     */
-    public String getPositiveSuffix() {
-        return ((java.text.DecimalFormat)numberFormat).getPositiveSuffix();
-    }
-
-    /**
-     * Sets the positive suffix.
-     *
-     * <p>Example: 123%
-     * @param newValue the suffix
-     * @stable ICU 2.0
-     */
-    public void setPositiveSuffix(String newValue) {
-        ((java.text.DecimalFormat)numberFormat).setPositiveSuffix(newValue);
-    }
-
-    /**
-     * Returns the negative suffix.
-     *
-     * <p>Examples: -123%, ($123) (with positive suffixes)
-     *
-     * @return the suffix
-     * @stable ICU 2.0
-     */
-    public String getNegativeSuffix() {
-        return ((java.text.DecimalFormat)numberFormat).getNegativeSuffix();
-    }
-
-    /**
-     * Sets the positive suffix.
-     *
-     * <p>Examples: 123%
-     * @param newValue the suffix
-     * @stable ICU 2.0
-     */
-    public void setNegativeSuffix(String newValue) {
-        ((java.text.DecimalFormat)numberFormat).setNegativeSuffix(newValue);
-    }
-
-    /**
-     * Returns the multiplier for use in percent, permill, etc. For a percentage, set the
-     * suffixes to have "%" and the multiplier to be 100. (For Arabic, use arabic percent
-     * symbol). For a permill, set the suffixes to have "\u2031" and the multiplier to be
-     * 1000.
-     *
-     * <p>Examples: with 100, 1.23 -> "123", and "123" -> 1.23
-     *
-     * @return the multiplier
-     * @stable ICU 2.0
-     */
-    public int getMultiplier() {
-        return ((java.text.DecimalFormat)numberFormat).getMultiplier();
-    }
-
-    /**
-     * Sets the multiplier for use in percent, permill, etc. For a percentage, set the
-     * suffixes to have "%" and the multiplier to be 100. (For Arabic, use arabic percent
-     * symbol). For a permill, set the suffixes to have "\u2031" and the multiplier to be
-     * 1000.
-     *
-     * <p>Examples: with 100, 1.23 -> "123", and "123" -> 1.23
-     *
-     * @param newValue the multiplier
-     * @stable ICU 2.0
-     */
-    public void setMultiplier(int newValue) {
-        ((java.text.DecimalFormat)numberFormat).setMultiplier(newValue);
-    }
-
-//    /**
-//     * {@icu} Returns the rounding increment.
-//     *
-//     * @return A positive rounding increment, or <code>null</code> if rounding is not in
-//     * effect.
-//     * @see #setRoundingIncrement
-//     * @see #getRoundingMode
-//     * @see #setRoundingMode
-//     * @stable ICU 2.0
-//     */
-//    public BigDecimal getRoundingIncrement() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the rounding increment. This method also controls whether rounding is
-//     * enabled.
-//     *
-//     * @param newValue A positive rounding increment, or <code>null</code> or
-//     * <code>BigDecimal(0.0)</code> to disable rounding.
-//     * @throws IllegalArgumentException if <code>newValue</code> is < 0.0
-//     * @see #getRoundingIncrement
-//     * @see #getRoundingMode
-//     * @see #setRoundingMode
-//     * @stable ICU 2.0
-//     */
-//    public void setRoundingIncrement(java.math.BigDecimal newValue) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the rounding increment. This method also controls whether rounding is
-//     * enabled.
-//     *
-//     * @param newValue A positive rounding increment, or <code>null</code> or
-//     * <code>BigDecimal(0.0)</code> to disable rounding.
-//     * @throws IllegalArgumentException if <code>newValue</code> is < 0.0
-//     * @see #getRoundingIncrement
-//     * @see #getRoundingMode
-//     * @see #setRoundingMode
-//     * @stable ICU 3.6
-//     */
-//    public void setRoundingIncrement(BigDecimal newValue) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the rounding increment. This method also controls whether rounding is
-//     * enabled.
-//     *
-//     * @param newValue A positive rounding increment, or 0.0 to disable rounding.
-//     * @throws IllegalArgumentException if <code>newValue</code> is < 0.0
-//     * @see #getRoundingIncrement
-//     * @see #getRoundingMode
-//     * @see #setRoundingMode
-//     * @stable ICU 2.0
-//     */
-//    public void setRoundingIncrement(double newValue) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Returns the rounding mode.
-//     *
-//     * @return A rounding mode, between <code>BigDecimal.ROUND_UP</code> and
-//     * <code>BigDecimal.ROUND_UNNECESSARY</code>.
-//     * @see #setRoundingIncrement
-//     * @see #getRoundingIncrement
-//     * @see #setRoundingMode
-//     * @see java.math.BigDecimal
-//     * @stable ICU 2.0
-//     */
-//    public int getRoundingMode() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Sets the rounding mode. This has no effect unless the rounding increment is greater
-//     * than zero.
-//     *
-//     * @param roundingMode A rounding mode, between <code>BigDecimal.ROUND_UP</code> and
-//     * <code>BigDecimal.ROUND_UNNECESSARY</code>.
-//     * @exception IllegalArgumentException if <code>roundingMode</code> is unrecognized.
-//     * @see #setRoundingIncrement
-//     * @see #getRoundingIncrement
-//     * @see #getRoundingMode
-//     * @see java.math.BigDecimal
-//     * @stable ICU 2.0
-//     */
-//    public void setRoundingMode(int roundingMode) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Returns the width to which the output of <code>format()</code> is padded. The width is
-//     * counted in 16-bit code units.
-//     *
-//     * @return the format width, or zero if no padding is in effect
-//     * @see #setFormatWidth
-//     * @see #getPadCharacter
-//     * @see #setPadCharacter
-//     * @see #getPadPosition
-//     * @see #setPadPosition
-//     * @stable ICU 2.0
-//     */
-//    public int getFormatWidth() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Sets the width to which the output of <code>format()</code> is
-//     * padded. The width is counted in 16-bit code units.  This method
-//     * also controls whether padding is enabled.
-//     *
-//     * @param width the width to which to pad the result of
-//     * <code>format()</code>, or zero to disable padding
-//     * @exception IllegalArgumentException if <code>width</code> is < 0
-//     * @see #getFormatWidth
-//     * @see #getPadCharacter
-//     * @see #setPadCharacter
-//     * @see #getPadPosition
-//     * @see #setPadPosition
-//     * @stable ICU 2.0
-//     */
-//    public void setFormatWidth(int width) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the character used to pad to the format width. The default is ' '.
-//     *
-//     * @return the pad character
-//     * @see #setFormatWidth
-//     * @see #getFormatWidth
-//     * @see #setPadCharacter
-//     * @see #getPadPosition
-//     * @see #setPadPosition
-//     * @stable ICU 2.0
-//     */
-//    public char getPadCharacter() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the character used to pad to the format width. If padding is not
-//     * enabled, then this will take effect if padding is later enabled.
-//     *
-//     * @param padChar the pad character
-//     * @see #setFormatWidth
-//     * @see #getFormatWidth
-//     * @see #getPadCharacter
-//     * @see #getPadPosition
-//     * @see #setPadPosition
-//     * @stable ICU 2.0
-//     */
-//    public void setPadCharacter(char padChar) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the position at which padding will take place. This is the location at
-//     * which padding will be inserted if the result of <code>format()</code> is shorter
-//     * than the format width.
-//     *
-//     * @return the pad position, one of <code>PAD_BEFORE_PREFIX</code>,
-//     *         <code>PAD_AFTER_PREFIX</code>, <code>PAD_BEFORE_SUFFIX</code>, or
-//     *         <code>PAD_AFTER_SUFFIX</code>.
-//     * @see #setFormatWidth
-//     * @see #getFormatWidth
-//     * @see #setPadCharacter
-//     * @see #getPadCharacter
-//     * @see #setPadPosition
-//     * @see #PAD_BEFORE_PREFIX
-//     * @see #PAD_AFTER_PREFIX
-//     * @see #PAD_BEFORE_SUFFIX
-//     * @see #PAD_AFTER_SUFFIX
-//     * @stable ICU 2.0
-//     */
-//    public int getPadPosition() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the position at which padding will take place. This is the location at
-//     * which padding will be inserted if the result of <code>format()</code> is shorter
-//     * than the format width. This has no effect unless padding is enabled.
-//     *
-//     * @param padPos the pad position, one of <code>PAD_BEFORE_PREFIX</code>,
-//     * <code>PAD_AFTER_PREFIX</code>, <code>PAD_BEFORE_SUFFIX</code>, or
-//     * <code>PAD_AFTER_SUFFIX</code>.
-//     * @exception IllegalArgumentException if the pad position in unrecognized
-//     * @see #setFormatWidth
-//     * @see #getFormatWidth
-//     * @see #setPadCharacter
-//     * @see #getPadCharacter
-//     * @see #getPadPosition
-//     * @see #PAD_BEFORE_PREFIX
-//     * @see #PAD_AFTER_PREFIX
-//     * @see #PAD_BEFORE_SUFFIX
-//     * @see #PAD_AFTER_SUFFIX
-//     * @stable ICU 2.0
-//     */
-//    public void setPadPosition(int padPos) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns whether or not scientific notation is used.
-//     *
-//     * @return true if this object formats and parses scientific notation
-//     * @see #setScientificNotation
-//     * @see #getMinimumExponentDigits
-//     * @see #setMinimumExponentDigits
-//     * @see #isExponentSignAlwaysShown
-//     * @see #setExponentSignAlwaysShown
-//     * @stable ICU 2.0
-//     */
-//    public boolean isScientificNotation() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets whether or not scientific notation is used. When scientific notation is
-//     * used, the effective maximum number of integer digits is <= 8. If the maximum number
-//     * of integer digits is set to more than 8, the effective maximum will be 1. This
-//     * allows this call to generate a 'default' scientific number format without
-//     * additional changes.
-//     *
-//     * @param useScientific true if this object formats and parses scientific notation
-//     * @see #isScientificNotation
-//     * @see #getMinimumExponentDigits
-//     * @see #setMinimumExponentDigits
-//     * @see #isExponentSignAlwaysShown
-//     * @see #setExponentSignAlwaysShown
-//     * @stable ICU 2.0
-//     */
-//    public void setScientificNotation(boolean useScientific) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the minimum exponent digits that will be shown.
-//     *
-//     * @return the minimum exponent digits that will be shown
-//     * @see #setScientificNotation
-//     * @see #isScientificNotation
-//     * @see #setMinimumExponentDigits
-//     * @see #isExponentSignAlwaysShown
-//     * @see #setExponentSignAlwaysShown
-//     * @stable ICU 2.0
-//     */
-//    public byte getMinimumExponentDigits() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the minimum exponent digits that will be shown. This has no effect
-//     * unless scientific notation is in use.
-//     *
-//     * @param minExpDig a value >= 1 indicating the fewest exponent
-//     * digits that will be shown
-//     * @exception IllegalArgumentException if <code>minExpDig</code> < 1
-//     * @see #setScientificNotation
-//     * @see #isScientificNotation
-//     * @see #getMinimumExponentDigits
-//     * @see #isExponentSignAlwaysShown
-//     * @see #setExponentSignAlwaysShown
-//     * @stable ICU 2.0
-//     */
-//    public void setMinimumExponentDigits(byte minExpDig) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns whether the exponent sign is always shown.
-//     *
-//     * @return true if the exponent is always prefixed with either the localized minus
-//     * sign or the localized plus sign, false if only negative exponents are prefixed with
-//     * the localized minus sign.
-//     * @see #setScientificNotation
-//     * @see #isScientificNotation
-//     * @see #setMinimumExponentDigits
-//     * @see #getMinimumExponentDigits
-//     * @see #setExponentSignAlwaysShown
-//     * @stable ICU 2.0
-//     */
-//    public boolean isExponentSignAlwaysShown() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets whether the exponent sign is always shown. This has no effect unless
-//     * scientific notation is in use.
-//     *
-//     * @param expSignAlways true if the exponent is always prefixed with either the
-//     * localized minus sign or the localized plus sign, false if only negative exponents
-//     * are prefixed with the localized minus sign.
-//     * @see #setScientificNotation
-//     * @see #isScientificNotation
-//     * @see #setMinimumExponentDigits
-//     * @see #getMinimumExponentDigits
-//     * @see #isExponentSignAlwaysShown
-//     * @stable ICU 2.0
-//     */
-//    public void setExponentSignAlwaysShown(boolean expSignAlways) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Returns the grouping size. Grouping size is the number of digits between grouping
-     * separators in the integer portion of a number. For example, in the number
-     * "123,456.78", the grouping size is 3.
-     *
-     * @see #setGroupingSize
-     * @see NumberFormat#isGroupingUsed
-     * @see DecimalFormatSymbols#getGroupingSeparator
-     * @stable ICU 2.0
-     */
-    public int getGroupingSize() {
-        return ((java.text.DecimalFormat)numberFormat).getGroupingSize();
-    }
-
-    /**
-     * Sets the grouping size. Grouping size is the number of digits between grouping
-     * separators in the integer portion of a number. For example, in the number
-     * "123,456.78", the grouping size is 3.
-     *
-     * @see #getGroupingSize
-     * @see NumberFormat#setGroupingUsed
-     * @see DecimalFormatSymbols#setGroupingSeparator
-     * @stable ICU 2.0
-     */
-    public void setGroupingSize(int newValue) {
-        ((java.text.DecimalFormat)numberFormat).setGroupingSize(newValue);
-    }
-
-//    /**
-//     * {@icu} Returns the secondary grouping size. In some locales one grouping interval
-//     * is used for the least significant integer digits (the primary grouping size), and
-//     * another is used for all others (the secondary grouping size). A formatter
-//     * supporting a secondary grouping size will return a positive integer unequal to the
-//     * primary grouping size returned by <code>getGroupingSize()</code>. For example, if
-//     * the primary grouping size is 4, and the secondary grouping size is 2, then the
-//     * number 123456789 formats as "1,23,45,6789", and the pattern appears as "#,##,###0".
-//     *
-//     * @return the secondary grouping size, or a value less than one if there is none
-//     * @see #setSecondaryGroupingSize
-//     * @see NumberFormat#isGroupingUsed
-//     * @see DecimalFormatSymbols#getGroupingSeparator
-//     * @stable ICU 2.0
-//     */
-//    public int getSecondaryGroupingSize() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the secondary grouping size. If set to a value less than 1, then
-//     * secondary grouping is turned off, and the primary grouping size is used for all
-//     * intervals, not just the least significant.
-//     *
-//     * @see #getSecondaryGroupingSize
-//     * @see NumberFormat#setGroupingUsed
-//     * @see DecimalFormatSymbols#setGroupingSeparator
-//     * @stable ICU 2.0
-//     */
-//    public void setSecondaryGroupingSize(int newValue) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the MathContext used by this format.
-//     *
-//     * @return desired MathContext
-//     * @see #getMathContext
-//     * @stable ICU 4.2
-//     */
-//    public MathContext getMathContextICU() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the MathContext used by this format.
-//     *
-//     * @return desired MathContext
-//     * @see #getMathContext
-//     * @stable ICU 4.2
-//     */
-//    public java.math.MathContext getMathContext() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the MathContext used by this format.
-//     *
-//     * @param newValue desired MathContext
-//     * @see #getMathContext
-//     * @stable ICU 4.2
-//     */
-//    public void setMathContextICU(MathContext newValue) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the MathContext used by this format.
-//     *
-//     * @param newValue desired MathContext
-//     * @see #getMathContext
-//     * @stable ICU 4.2
-//     */
-//    public void setMathContext(java.math.MathContext newValue) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Returns the behavior of the decimal separator with integers. (The decimal
-     * separator will always appear with decimals.)  <p> Example: Decimal ON: 12345 ->
-     * 12345.; OFF: 12345 -> 12345
-     *
-     * @stable ICU 2.0
-     */
-    public boolean isDecimalSeparatorAlwaysShown() {
-        return ((java.text.DecimalFormat)numberFormat).isDecimalSeparatorAlwaysShown();
-    }
-
-    /**
-     * Sets the behavior of the decimal separator with integers. (The decimal separator
-     * will always appear with decimals.)
-     *
-     * <p>This only affects formatting, and only where there might be no digits after the
-     * decimal point, e.g., if true, 3456.00 -> "3,456." if false, 3456.00 -> "3456" This
-     * is independent of parsing. If you want parsing to stop at the decimal point, use
-     * setParseIntegerOnly.
-     *
-     * <p>
-     * Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
-     *
-     * @stable ICU 2.0
-     */
-    public void setDecimalSeparatorAlwaysShown(boolean newValue) {
-        ((java.text.DecimalFormat)numberFormat).setDecimalSeparatorAlwaysShown(newValue);
-    }
-
-//    /**
-//     * {@icu} Returns a copy of the CurrencyPluralInfo used by this format. It might
-//     * return null if the decimal format is not a plural type currency decimal
-//     * format. Plural type currency decimal format means either the pattern in the decimal
-//     * format contains 3 currency signs, or the decimal format is initialized with
-//     * PLURALCURRENCYSTYLE.
-//     *
-//     * @return desired CurrencyPluralInfo
-//     * @see CurrencyPluralInfo
-//     * @stable ICU 4.2
-//     */
-//    public CurrencyPluralInfo getCurrencyPluralInfo() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the CurrencyPluralInfo used by this format. The format uses a copy of
-//     * the provided information.
-//     *
-//     * @param newInfo desired CurrencyPluralInfo
-//     * @see CurrencyPluralInfo
-//     * @stable ICU 4.2
-//     */
-//    public void setCurrencyPluralInfo(CurrencyPluralInfo newInfo) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Overrides clone.
-     * @stable ICU 2.0
-     */
-    public Object clone() {
-        return new DecimalFormatSymbols((java.text.DecimalFormatSymbols)numberFormat.clone());
-    }
-
-    /**
-     * Overrides equals.
-     * @stable ICU 2.0
-     */
-    public boolean equals(Object obj) {
-        return super.equals(obj);
-    }
-
-    /**
-     * Overrides hashCode.
-     * @stable ICU 2.0
-     */
-    public int hashCode() {
-        return super.hashCode();
-    }
-
-    /**
-     * Synthesizes a pattern string that represents the current state of this Format
-     * object.
-     *
-     * @see #applyPattern
-     * @stable ICU 2.0
-     */
-    public String toPattern() {
-        return ((java.text.DecimalFormat)numberFormat).toPattern();
-    }
-
-    /**
-     * Synthesizes a localized pattern string that represents the current state of this
-     * Format object.
-     *
-     * @see #applyPattern
-     * @stable ICU 2.0
-     */
-    public String toLocalizedPattern() {
-        return ((java.text.DecimalFormat)numberFormat).toLocalizedPattern();
-    }
-
-    /**
-     * Formats the object to an attributed string, and return the corresponding iterator.
-     *
-     * @stable ICU 3.6
-     */
-    public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
-        AttributedCharacterIterator it = numberFormat.formatToCharacterIterator(obj);
-
-        // Extract formatted String first
-        StringBuilder sb = new StringBuilder();
-        for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
-            sb.append(c);
-        }
-
-        // Create AttributedString
-        AttributedString attrstr = new AttributedString(sb.toString());
-
-        // Map JDK Field to ICU Field
-        int idx = 0;
-        it.first();
-        while (idx < it.getEndIndex()) {
-            int end = it.getRunLimit();
-            Map<Attribute, Object> attributes = it.getAttributes();
-            if (attributes != null) {
-                for (Entry<Attribute, Object> entry : attributes.entrySet()) {
-                    Attribute attr = entry.getKey();
-                    Object val = entry.getValue();
-                    if (attr.equals(java.text.NumberFormat.Field.CURRENCY)) {
-                        val = attr = Field.CURRENCY;
-                    } else if (attr.equals(java.text.NumberFormat.Field.DECIMAL_SEPARATOR)) {
-                        val = attr = Field.DECIMAL_SEPARATOR;
-                    } else if (attr.equals(java.text.NumberFormat.Field.EXPONENT)) {
-                        val = attr = Field.EXPONENT;
-                    } else if (attr.equals(java.text.NumberFormat.Field.EXPONENT_SIGN)) {
-                        val = attr = Field.EXPONENT_SIGN;
-                    } else if (attr.equals(java.text.NumberFormat.Field.EXPONENT_SYMBOL)) {
-                        val = attr = Field.EXPONENT_SYMBOL;
-                    } else if (attr.equals(java.text.NumberFormat.Field.FRACTION)) {
-                        val = attr = Field.FRACTION;
-                    } else if (attr.equals(java.text.NumberFormat.Field.GROUPING_SEPARATOR)) {
-                        val = attr = Field.GROUPING_SEPARATOR;
-                    } else if (attr.equals(java.text.NumberFormat.Field.INTEGER)) {
-                        val = attr = Field.INTEGER;
-                    } else if (attr.equals(java.text.NumberFormat.Field.PERCENT)) {
-                        val = attr = Field.PERCENT;
-                    } else if (attr.equals(java.text.NumberFormat.Field.PERMILLE)) {
-                        val = attr = Field.PERMILLE;
-                    } else if (attr.equals(java.text.NumberFormat.Field.SIGN)) {
-                        val = attr = Field.SIGN;
-                    }
-                    attrstr.addAttribute(attr, val, idx, end);
-                }
-            }
-            idx = end;
-            while (it.getIndex() < idx) {
-                it.next();
-            }
-        }
-
-        return attrstr.getIterator();
-    }
-
-    /**
-     * Applies the given pattern to this Format object. A pattern is a short-hand
-     * specification for the various formatting properties. These properties can also be
-     * changed individually through the various setter methods.
-     *
-     * <p>There is no limit to integer digits are set by this routine, since that is the
-     * typical end-user desire; use setMaximumInteger if you want to set a real value. For
-     * negative numbers, use a second pattern, separated by a semicolon
-     *
-     * <p>Example "#,#00.0#" -> 1,234.56
-     *
-     * <p>This means a minimum of 2 integer digits, 1 fraction digit, and a maximum of 2
-     * fraction digits.
-     *
-     * <p>Example: "#,#00.0#;(#,#00.0#)" for negatives in parentheses.
-     *
-     * <p>In negative patterns, the minimum and maximum counts are ignored; these are
-     * presumed to be set in the positive pattern.
-     *
-     * @stable ICU 2.0
-     */
-    public void applyPattern(String pattern) {
-        ((java.text.DecimalFormat)numberFormat).applyPattern(pattern);
-    }
-
-    /**
-     * Applies the given pattern to this Format object. The pattern is assumed to be in a
-     * localized notation. A pattern is a short-hand specification for the various
-     * formatting properties. These properties can also be changed individually through
-     * the various setter methods.
-     *
-     * <p>There is no limit to integer digits are set by this routine, since that is the
-     * typical end-user desire; use setMaximumInteger if you want to set a real value. For
-     * negative numbers, use a second pattern, separated by a semicolon
-     *
-     * <p>Example "#,#00.0#" -> 1,234.56
-     *
-     * <p>This means a minimum of 2 integer digits, 1 fraction digit, and a maximum of 2
-     * fraction digits.
-     *
-     * <p>Example: "#,#00.0#;(#,#00.0#)" for negatives in parantheses.
-     *
-     * <p>In negative patterns, the minimum and maximum counts are ignored; these are
-     * presumed to be set in the positive pattern.
-     *
-     * @stable ICU 2.0
-     */
-    public void applyLocalizedPattern(String pattern) {
-        ((java.text.DecimalFormat)numberFormat).applyLocalizedPattern(pattern);
-    }
-
-    /**
-     * Sets the maximum number of digits allowed in the integer portion of a number. This
-     * override limits the integer digit count to 309.
-     *
-     * @see NumberFormat#setMaximumIntegerDigits
-     * @stable ICU 2.0
-     */
-    public void setMaximumIntegerDigits(int newValue) {
-        super.setMaximumIntegerDigits(newValue);
-    }
-
-    /**
-     * Sets the minimum number of digits allowed in the integer portion of a number. This
-     * override limits the integer digit count to 309.
-     *
-     * @see NumberFormat#setMinimumIntegerDigits
-     * @stable ICU 2.0
-     */
-    public void setMinimumIntegerDigits(int newValue) {
-        super.setMinimumIntegerDigits(newValue);
-    }
-
-//    /**
-//     * {@icu} Returns the minimum number of significant digits that will be
-//     * displayed. This value has no effect unless {@link #areSignificantDigitsUsed()}
-//     * returns true.
-//     *
-//     * @return the fewest significant digits that will be shown
-//     * @stable ICU 3.0
-//     */
-//    public int getMinimumSignificantDigits() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the maximum number of significant digits that will be
-//     * displayed. This value has no effect unless {@link #areSignificantDigitsUsed()}
-//     * returns true.
-//     *
-//     * @return the most significant digits that will be shown
-//     * @stable ICU 3.0
-//     */
-//    public int getMaximumSignificantDigits() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the minimum number of significant digits that will be displayed. If
-//     * <code>min</code> is less than one then it is set to one. If the maximum significant
-//     * digits count is less than <code>min</code>, then it is set to
-//     * <code>min</code>. This value has no effect unless {@link #areSignificantDigitsUsed()}
-//     * returns true.
-//     *
-//     * @param min the fewest significant digits to be shown
-//     * @stable ICU 3.0
-//     */
-//    public void setMinimumSignificantDigits(int min) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the maximum number of significant digits that will be displayed. If
-//     * <code>max</code> is less than one then it is set to one. If the minimum significant
-//     * digits count is greater than <code>max</code>, then it is set to
-//     * <code>max</code>. This value has no effect unless {@link #areSignificantDigitsUsed()}
-//     * returns true.
-//     *
-//     * @param max the most significant digits to be shown
-//     * @stable ICU 3.0
-//     */
-//    public void setMaximumSignificantDigits(int max) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns true if significant digits are in use or false if integer and
-//     * fraction digit counts are in use.
-//     *
-//     * @return true if significant digits are in use
-//     * @stable ICU 3.0
-//     */
-//    public boolean areSignificantDigitsUsed() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets whether significant digits are in use, or integer and fraction digit
-//     * counts are in use.
-//     *
-//     * @param useSignificantDigits true to use significant digits, or false to use integer
-//     * and fraction digit counts
-//     * @stable ICU 3.0
-//     */
-//    public void setSignificantDigitsUsed(boolean useSignificantDigits) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Sets the <tt>Currency</tt> object used to display currency amounts. This takes
-     * effect immediately, if this format is a currency format. If this format is not a
-     * currency format, then the currency object is used if and when this object becomes a
-     * currency format through the application of a new pattern.
-     *
-     * @param theCurrency new currency object to use. Must not be null.
-     * @stable ICU 2.2
-     */
-    public void setCurrency(Currency theCurrency) {
-        super.setCurrency(theCurrency);
-    }
-
-    /**
-     * Sets the maximum number of digits allowed in the fraction portion of a number. This
-     * override limits the fraction digit count to 340.
-     *
-     * @see NumberFormat#setMaximumFractionDigits
-     * @stable ICU 2.0
-     */
-    public void setMaximumFractionDigits(int newValue) {
-        super.setMaximumFractionDigits(newValue);
-    }
-
-    /**
-     * Sets the minimum number of digits allowed in the fraction portion of a number. This
-     * override limits the fraction digit count to 340.
-     *
-     * @see NumberFormat#setMinimumFractionDigits
-     * @stable ICU 2.0
-     */
-    public void setMinimumFractionDigits(int newValue) {
-        super.setMinimumFractionDigits(newValue);
-    }
-
-    /**
-     * Sets whether {@link #parse(String, ParsePosition)} returns BigDecimal. The
-     * default value is false.
-     *
-     * @param value true if {@link #parse(String, ParsePosition)}
-     * returns BigDecimal.
-     * @stable ICU 3.6
-     */
-    public void setParseBigDecimal(boolean value) {
-        ((java.text.DecimalFormat)numberFormat).setParseBigDecimal(value);
-    }
-
-    /**
-     * Returns whether {@link #parse(String, ParsePosition)} returns BigDecimal.
-     *
-     * @return true if {@link #parse(String, ParsePosition)} returns BigDecimal.
-     * @stable ICU 3.6
-     */
-    public boolean isParseBigDecimal() {
-        return ((java.text.DecimalFormat)numberFormat).isParseBigDecimal();
-    }
-
-    // ----------------------------------------------------------------------
-    // CONSTANTS
-    // ----------------------------------------------------------------------
-
-    /**
-     * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to
-     * specify pad characters inserted before the prefix.
-     *
-     * @see #setPadPosition
-     * @see #getPadPosition
-     * @see #PAD_AFTER_PREFIX
-     * @see #PAD_BEFORE_SUFFIX
-     * @see #PAD_AFTER_SUFFIX
-     * @stable ICU 2.0
-     */
-    public static final int PAD_BEFORE_PREFIX = 0;
-
-    /**
-     * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to
-     * specify pad characters inserted after the prefix.
-     *
-     * @see #setPadPosition
-     * @see #getPadPosition
-     * @see #PAD_BEFORE_PREFIX
-     * @see #PAD_BEFORE_SUFFIX
-     * @see #PAD_AFTER_SUFFIX
-     * @stable ICU 2.0
-     */
-    public static final int PAD_AFTER_PREFIX = 1;
-
-    /**
-     * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to
-     * specify pad characters inserted before the suffix.
-     *
-     * @see #setPadPosition
-     * @see #getPadPosition
-     * @see #PAD_BEFORE_PREFIX
-     * @see #PAD_AFTER_PREFIX
-     * @see #PAD_AFTER_SUFFIX
-     * @stable ICU 2.0
-     */
-    public static final int PAD_BEFORE_SUFFIX = 2;
-
-    /**
-     * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to
-     * specify pad characters inserted after the suffix.
-     *
-     * @see #setPadPosition
-     * @see #getPadPosition
-     * @see #PAD_BEFORE_PREFIX
-     * @see #PAD_AFTER_PREFIX
-     * @see #PAD_BEFORE_SUFFIX
-     * @stable ICU 2.0
-     */
-    public static final int PAD_AFTER_SUFFIX = 3;
-}
-
-// eof
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormatSymbols.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormatSymbols.java
deleted file mode 100644
index 88dbe0a..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/DecimalFormatSymbols.java
+++ /dev/null
@@ -1,710 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 1996-2012, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.text;
-
-
-import java.io.Serializable;
-import java.util.Locale;
-
-import com.ibm.icu.util.Currency;
-import com.ibm.icu.util.ULocale;
-import com.ibm.icu.util.ULocale.Category;
-
-/**
- * This class represents the set of symbols (such as the decimal separator, the
- * grouping separator, and so on) needed by <code>DecimalFormat</code> to format
- * numbers. <code>DecimalFormat</code> creates for itself an instance of
- * <code>DecimalFormatSymbols</code> from its locale data.  If you need to
- * change any of these symbols, you can get the
- * <code>DecimalFormatSymbols</code> object from your <code>DecimalFormat</code>
- * and modify it.
- *
- * <p><strong>This is an enhanced version of <code>DecimalFormatSymbols</code> that
- * is based on the standard version in the JDK.  New or changed functionality
- * is labeled
- * <strong><font face=helvetica color=red>NEW</font></strong>.</strong>
- *
- * @see          java.util.Locale
- * @see          DecimalFormat
- * @author       Mark Davis
- * @author       Alan Liu
- * @stable ICU 2.0
- */
-final public class DecimalFormatSymbols implements Cloneable, Serializable {
-
-    private static final long serialVersionUID =1L;
-
-    /**
-     * @internal
-     */
-    public final java.text.DecimalFormatSymbols dfs;
-
-    /**
-     * @internal
-     */
-    public DecimalFormatSymbols(java.text.DecimalFormatSymbols delegate) {
-        this.dfs = delegate;
-    }
-        
-    /**
-     * Create a DecimalFormatSymbols object for the default locale.
-     * @stable ICU 2.0
-     */
-    public DecimalFormatSymbols() {
-        this(new java.text.DecimalFormatSymbols(ULocale.getDefault(Category.FORMAT).toLocale()));
-    }
-        
-    /**
-     * Create a DecimalFormatSymbols object for the given locale.
-     * @param locale the locale
-     * @stable ICU 2.0
-     */
-    public DecimalFormatSymbols(Locale locale) {
-        this(new java.text.DecimalFormatSymbols(locale));
-    }
-        
-    /**
-     * Create a DecimalFormatSymbols object for the given locale.
-     * @param locale the locale
-     * @stable ICU 3.2
-     */
-    public DecimalFormatSymbols(ULocale locale) {
-        this(new java.text.DecimalFormatSymbols(locale.toLocale()));
-    }
-
-    /**
-     * Returns a DecimalFormatSymbols instance for the default locale.
-     *
-     * <p><strong>Note:</strong> Unlike
-     * <code>java.text.DecimalFormatSymbols#getInstance</code>, this method simply returns
-     * <code>new com.ibm.icu.text.DecimalFormatSymbols()</code>.  ICU currently does not
-     * support <code>DecimalFormatSymbolsProvider</code>, which was introduced in Java 6.
-     *
-     * @return A DecimalFormatSymbols instance.
-     * @stable ICU 3.8
-     */
-    public static DecimalFormatSymbols getInstance() {
-        return new DecimalFormatSymbols();
-    }
-
-    /**
-     * Returns a DecimalFormatSymbols instance for the given locale.
-     *
-     * <p><strong>Note:</strong> Unlike
-     * <code>java.text.DecimalFormatSymbols#getInstance</code>, this method simply returns
-     * <code>new com.ibm.icu.text.DecimalFormatSymbols(locale)</code>.  ICU currently does
-     * not support <code>DecimalFormatSymbolsProvider</code>, which was introduced in Java
-     * 6.
-     *
-     * @param locale the locale.
-     * @return A DecimalFormatSymbols instance.
-     * @stable ICU 3.8
-     */
-    public static DecimalFormatSymbols getInstance(Locale locale) {
-        return new DecimalFormatSymbols(locale);
-    }
-
-    /**
-     * Returns a DecimalFormatSymbols instance for the given locale.
-     *
-     * <p><strong>Note:</strong> Unlike
-     * <code>java.text.DecimalFormatSymbols#getInstance</code>, this method simply returns
-     * <code>new com.ibm.icu.text.DecimalFormatSymbols(locale)</code>.  ICU currently does
-     * not support <code>DecimalFormatSymbolsProvider</code>, which was introduced in Java
-     * 6.
-     *
-     * @param locale the locale.
-     * @return A DecimalFormatSymbols instance.
-     * @stable ICU 3.8
-     */
-    public static DecimalFormatSymbols getInstance(ULocale locale) {
-        return new DecimalFormatSymbols(locale);
-    }
-
-//    /**
-//     * Returns an array of all locales for which the <code>getInstance</code> methods of
-//     * this class can return localized instances.
-//     *
-//     * <p><strong>Note:</strong> Unlike
-//     * <code>java.text.DecimalFormatSymbols#getAvailableLocales</code>, this method simply
-//     * returns the array of <code>Locale</code>s available for this class.  ICU currently
-//     * does not support <code>DecimalFormatSymbolsProvider</code>, which was introduced in
-//     * Java 6.
-//     *
-//     * @return An array of <code>Locale</code>s for which localized
-//     * <code>DecimalFormatSymbols</code> instances are available.
-//     * @stable ICU 3.8
-//     */
-//    public static Locale[] getAvailableLocales() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns an array of all locales for which the <code>getInstance</code>
-//     * methods of this class can return localized instances.
-//     *
-//     * <p><strong>Note:</strong> Unlike
-//     * <code>java.text.DecimalFormatSymbols#getAvailableLocales</code>, this method simply
-//     * returns the array of <code>ULocale</code>s available in this class.  ICU currently
-//     * does not support <code>DecimalFormatSymbolsProvider</code>, which was introduced in
-//     * Java 6.
-//     *
-//     * @return An array of <code>ULocale</code>s for which localized
-//     * <code>DecimalFormatSymbols</code> instances are available.
-//     * @stable ICU 3.8 (retain)
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public static ULocale[] getAvailableULocales() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Return the character used for zero. Different for Arabic, etc.
-     * @return the character
-     * @stable ICU 2.0
-     */
-    public char getZeroDigit() {
-        return dfs.getZeroDigit();
-    }
-        
-    /**
-     * Set the character used for zero.
-     * @param zeroDigit the zero character.
-     * @stable ICU 2.0
-     */
-    public void setZeroDigit(char zeroDigit) {
-        dfs.setZeroDigit(zeroDigit);
-    }
-
-//    /**
-//     * Returns the character used to represent a significant digit in a pattern.
-//     * @return the significant digit pattern character
-//     * @stable ICU 3.0
-//     */
-//    public char getSignificantDigit() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Sets the character used to represent a significant digit in a pattern.
-//     * @param sigDigit the significant digit pattern character
-//     * @stable ICU 3.0
-//     */
-//    public void setSignificantDigit(char sigDigit) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Return the character used for thousands separator. Different for French, etc.
-     * @return the thousands character
-     * @stable ICU 2.0
-     */
-    public char getGroupingSeparator() {
-        return dfs.getGroupingSeparator();
-    }
-        
-    /**
-     * Set the character used for thousands separator. Different for French, etc.
-     * @param groupingSeparator the thousands character
-     * @stable ICU 2.0
-     */
-    public void setGroupingSeparator(char groupingSeparator) {
-        dfs.setGroupingSeparator(groupingSeparator);
-    }
-        
-    /**
-     * Return the character used for decimal sign. Different for French, etc.
-     * @return the decimal character
-     * @stable ICU 2.0
-     */
-    public char getDecimalSeparator() {
-        return dfs.getDecimalSeparator();
-    }
-        
-    /**
-     * Set the character used for decimal sign. Different for French, etc.
-     * @param decimalSeparator the decimal character
-     * @stable ICU 2.0
-     */
-    public void setDecimalSeparator(char decimalSeparator) {
-        dfs.setDecimalSeparator(decimalSeparator);
-    }
-        
-    /**
-     * Return the character used for mille percent sign. Different for Arabic, etc.
-     * @return the mille percent character
-     * @stable ICU 2.0
-     */
-    public char getPerMill() {
-        return dfs.getPerMill();
-    }
-        
-    /**
-     * Set the character used for mille percent sign. Different for Arabic, etc.
-     * @param perMill the mille percent character
-     * @stable ICU 2.0
-     */
-    public void setPerMill(char perMill) {
-        dfs.setPerMill(perMill);
-    }
-        
-    /**
-     * Return the character used for percent sign. Different for Arabic, etc.
-     * @return the percent character
-     * @stable ICU 2.0
-     */
-    public char getPercent() {
-        return dfs.getPercent();
-    }
-        
-    /**
-     * Set the character used for percent sign. Different for Arabic, etc.
-     * @param percent the percent character
-     * @stable ICU 2.0
-     */
-    public void setPercent(char percent) {
-        dfs.setPercent(percent);
-    }
-        
-    /**
-     * Return the character used for a digit in a pattern.
-     * @return the digit pattern character
-     * @stable ICU 2.0
-     */
-    public char getDigit() {
-        return dfs.getDigit();
-    }
-        
-    /**
-     * Returns the array of characters used as digits, in order from 0 through 9
-     * @return The array
-     * @draft ICU 4.6
-     * @provisional This API might change or be removed in a future release.
-     */
-    public char[] getDigits() {
-        char [] digitArray = new char[10];
-        for ( int i = 0 ; i < 10 ; i++ ) {
-            digitArray[i] = (char) (getZeroDigit() + i);
-        }
-        return digitArray;
-    }
-    
-    /**
-     * Set the character used for a digit in a pattern.
-     * @param digit the digit pattern character
-     * @stable ICU 2.0
-     */
-    public void setDigit(char digit) {
-        dfs.setDigit(digit);
-    }
-        
-    /**
-     * Return the character used to separate positive and negative subpatterns
-     * in a pattern.
-     * @return the pattern separator character
-     * @stable ICU 2.0
-     */
-    public char getPatternSeparator() {
-        return dfs.getPatternSeparator();
-    }
-        
-    /**
-     * Set the character used to separate positive and negative subpatterns
-     * in a pattern.
-     * @param patternSeparator the pattern separator character
-     * @stable ICU 2.0
-     */
-    public void setPatternSeparator(char patternSeparator) {
-        dfs.setPatternSeparator(patternSeparator);
-    }
-        
-    /**
-     * Return the String used to represent infinity. Almost always left
-     * unchanged.
-     * @return the Infinity string
-     * @stable ICU 2.0
-     */
-    public String getInfinity() {
-        return dfs.getInfinity();
-    }
-        
-    /**
-     * Set the String used to represent infinity. Almost always left
-     * unchanged.
-     * @param infinity the Infinity String
-     * @stable ICU 2.0
-     */
-    public void setInfinity(String infinity) {
-        dfs.setInfinity(infinity);
-    }
-        
-    /**
-     * Return the String used to represent NaN. Almost always left
-     * unchanged.
-     * @return the NaN String
-     * @stable ICU 2.0
-     */
-    public String getNaN() {
-        return dfs.getNaN();
-    }
-        
-    /**
-     * Set the String used to represent NaN. Almost always left
-     * unchanged.
-     * @param NaN the NaN String
-     * @stable ICU 2.0
-     */
-    public void setNaN(String NaN) {
-        dfs.setNaN(NaN);
-    }
-        
-    /**
-     * Return the character used to represent minus sign. If no explicit
-     * negative format is specified, one is formed by prefixing
-     * minusSign to the positive format.
-     * @return the minus sign character
-     * @stable ICU 2.0
-     */
-    public char getMinusSign() {
-        return dfs.getMinusSign();
-    }
-        
-    /**
-     * Set the character used to represent minus sign. If no explicit
-     * negative format is specified, one is formed by prefixing
-     * minusSign to the positive format.
-     * @param minusSign the minus sign character
-     * @stable ICU 2.0
-     */
-    public void setMinusSign(char minusSign) {
-        dfs.setMinusSign(minusSign);
-    }
-        
-    /**
-     * Return the string denoting the local currency.
-     * @return the local currency String.
-     * @stable ICU 2.0
-     */
-    public String getCurrencySymbol() {
-        return dfs.getCurrencySymbol();
-    }
-        
-    /**
-     * Set the string denoting the local currency.
-     * @param currency the local currency String.
-     * @stable ICU 2.0
-     */
-    public void setCurrencySymbol(String currency) {
-        dfs.setCurrencySymbol(currency);
-    }
-
-    /**
-     * Returns the currency symbol, for JDK 1.4 compatibility only.
-     * ICU clients should use the Currency API directly.
-     * @return the currency used, or null
-     * @stable ICU 3.4
-     */
-    public Currency getCurrency() {
-        return new Currency(dfs.getCurrency());
-    }
-
-    /**
-     * Sets the currency.
-     *
-     * <p><strong>Note:</strong> ICU does not use the DecimalFormatSymbols for the currency
-     * any more.  This API is present for API compatibility only.
-     *
-     * <p>This also sets the currency symbol attribute to the currency's symbol
-     * in the DecimalFormatSymbols' locale, and the international currency
-     * symbol attribute to the currency's ISO 4217 currency code.
-     *
-     * @param currency the new currency to be used
-     * @throws NullPointerException if <code>currency</code> is null
-     * @see #setCurrencySymbol
-     * @see #setInternationalCurrencySymbol
-     *
-     * @stable ICU 3.4
-     */
-    public void setCurrency(Currency currency) {
-        dfs.setCurrency(java.util.Currency.getInstance(currency.getCurrencyCode()));
-    }
-
-    /**
-     * Return the international string denoting the local currency.
-     * @return the international string denoting the local currency
-     * @stable ICU 2.0
-     */
-    public String getInternationalCurrencySymbol() {
-        return dfs.getInternationalCurrencySymbol();
-    }
-        
-    /**
-     * Set the international string denoting the local currency.
-     * @param currency the international string denoting the local currency.
-     * @stable ICU 2.0
-     */
-    public void setInternationalCurrencySymbol(String currency) {
-        dfs.setInternationalCurrencySymbol(currency);
-    }
-        
-    /**
-     * Return the monetary decimal separator.
-     * @return the monetary decimal separator character
-     * @stable ICU 2.0
-     */
-    public char getMonetaryDecimalSeparator() {
-        return dfs.getMonetaryDecimalSeparator();
-    }
-        
-    /**
-     * Set the monetary decimal separator.
-     * @param sep the monetary decimal separator character
-     * @stable ICU 2.0
-     */
-    public void setMonetaryDecimalSeparator(char sep) {
-        dfs.setMonetaryDecimalSeparator(sep);
-    }
-
-//    /**
-//     * {@icu} Returns the monetary grouping separator.
-//     * @return the monetary grouping separator character
-//     * @stable ICU 3.6
-//     */
-//    public char getMonetaryGroupingSeparator() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Sets the monetary decimal separator.
-//     * @param sep the monetary decimal separator character
-//     * @stable ICU 3.6
-//     */
-//    public void setMonetaryGroupingSeparator(char sep) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the string used to separate the mantissa from the exponent.
-//     * Examples: "x10^" for 1.23x10^4, "E" for 1.23E4.
-//     * @return the localized exponent symbol, used in localized patterns
-//     * and formatted strings
-//     * @see #setExponentSeparator
-//     * @stable ICU 2.0
-//     */
-//    public String getExponentSeparator() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the string used to separate the mantissa from the exponent.
-//     * Examples: "x10^" for 1.23x10^4, "E" for 1.23E4.
-//     * @param exp the localized exponent symbol, used in localized patterns
-//     * and formatted strings
-//     * @see #getExponentSeparator
-//     * @stable ICU 2.0
-//     */
-//    public void setExponentSeparator(String exp) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the localized plus sign.
-//     * @return the plus sign, used in localized patterns and formatted
-//     * strings
-//     * @see #setPlusSign
-//     * @see #setMinusSign
-//     * @see #getMinusSign
-//     * @stable ICU 2.0
-//     */
-//    public char getPlusSign() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the localized plus sign.
-//     * @param plus the plus sign, used in localized patterns and formatted
-//     * strings
-//     * @see #getPlusSign
-//     * @see #setMinusSign
-//     * @see #getMinusSign
-//     * @stable ICU 2.0
-//     */
-//    public void setPlusSign(char plus) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the character used to pad numbers out to a specified width.  This is
-//     * not the pad character itself; rather, it is the special pattern character
-//     * <em>preceding</em> the pad character.  In the pattern "*_#,##0", '*' is the pad
-//     * escape, and '_' is the pad character.
-//     * @return the character
-//     * @see #setPadEscape
-//     * @see DecimalFormat#getFormatWidth
-//     * @see DecimalFormat#getPadPosition
-//     * @see DecimalFormat#getPadCharacter
-//     * @stable ICU 2.0
-//     */
-//    public char getPadEscape() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the character used to pad numbers out to a specified width.  This is not
-//     * the pad character itself; rather, it is the special pattern character
-//     * <em>preceding</em> the pad character.  In the pattern "*_#,##0", '*' is the pad
-//     * escape, and '_' is the pad character.
-//     * @see #getPadEscape
-//     * @see DecimalFormat#setFormatWidth
-//     * @see DecimalFormat#setPadPosition
-//     * @see DecimalFormat#setPadCharacter
-//     * @stable ICU 2.0
-//     */
-//    public void setPadEscape(char c) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Indicates the currency match pattern used in {@link #getPatternForCurrencySpacing}.
-//     * @stable ICU 4.2
-//     */
-//    public static final int CURRENCY_SPC_CURRENCY_MATCH = 0;
-//
-//    /**
-//     * {@icu} Indicates the surrounding match pattern used in {@link
-//     * #getPatternForCurrencySpacing}.
-//     * @stable ICU 4.2
-//     */
-//    public static final int CURRENCY_SPC_SURROUNDING_MATCH = 1;
-//
-//    /**
-//     * {@icu} Indicates the insertion value used in {@link #getPatternForCurrencySpacing}.
-//     * @stable ICU 4.4
-//     */
-//    public static final int CURRENCY_SPC_INSERT = 2;
-
-//    /**
-//     * {@icu} Returns the desired currency spacing value. Original values come from ICU's
-//     * CLDR data based on the locale provided during construction, and can be null.  These
-//     * values govern what and when text is inserted between a currency code/name/symbol
-//     * and the currency amount when formatting money.
-//     *
-//     * <p>For more information, see <a href="http://www.unicode.org/reports/tr35/#Currencies"
-//     * >UTS#35 section 5.10.2</a>.
-//     *
-//     * <p><strong>Note:</strong> ICU4J does not currently use this information.
-//     *
-//     * @param itemType one of CURRENCY_SPC_CURRENCY_MATCH, CURRENCY_SPC_SURROUNDING_MATCH
-//     * or CURRENCY_SPC_INSERT
-//     * @param beforeCurrency true to get the <code>beforeCurrency</code> values, false
-//     * to get the <code>afterCurrency</code> values.
-//     * @return the value, or null.
-//     * @see #setPatternForCurrencySpacing(int, boolean, String)
-//     * @stable ICU 4.2
-//     */
-//    public String getPatternForCurrencySpacing(int itemType, boolean beforeCurrency)  {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Sets the indicated currency spacing pattern or value. See {@link
-//     * #getPatternForCurrencySpacing} for more information.
-//     *
-//     * <p>Values for currency match and surrounding match must be {@link
-//     * com.ibm.icu.text.UnicodeSet} patterns. Values for insert can be any string.
-//     *
-//     * <p><strong>Note:</strong> ICU4J does not currently use this information.
-//     *
-//     * @param itemType one of CURRENCY_SPC_CURRENCY_MATCH, CURRENCY_SPC_SURROUNDING_MATCH
-//     * or CURRENCY_SPC_INSERT
-//     * @param beforeCurrency true if the pattern is for before the currency symbol.
-//     * false if the pattern is for after it.
-//     * @param  pattern string to override current setting; can be null.
-//     * @see #getPatternForCurrencySpacing(int, boolean)
-//     * @stable ICU 4.2
-//     */
-//    public void setPatternForCurrencySpacing(int itemType, boolean beforeCurrency, String pattern) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-
-//    /**
-//     * Returns the locale for which this object was constructed.
-//     * @return the locale for which this object was constructed
-//     * @stable ICU 2.0
-//     */
-//    public Locale getLocale() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Returns the locale for which this object was constructed.
-//     * @return the locale for which this object was constructed
-//     * @stable ICU 3.2
-//     */
-//    public ULocale getULocale() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the locale that was used to create this object, or null.
-//     * This may may differ from the locale requested at the time of
-//     * this object's creation.  For example, if an object is created
-//     * for locale <tt>en_US_CALIFORNIA</tt>, the actual data may be
-//     * drawn from <tt>en</tt> (the <i>actual</i> locale), and
-//     * <tt>en_US</tt> may be the most specific locale that exists (the
-//     * <i>valid</i> locale).
-//     *
-//     * <p>Note: The <i>actual</i> locale is returned correctly, but the <i>valid</i>
-//     * locale is not, in most cases.
-//     * @param type type of information requested, either {@link
-//     * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link
-//     * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}.
-//     * @return the information specified by <i>type</i>, or null if
-//     * this object was not constructed from locale data.
-//     * @see com.ibm.icu.util.ULocale
-//     * @see com.ibm.icu.util.ULocale#VALID_LOCALE
-//     * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
-//     * @draft ICU 2.8 (retain)
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public final ULocale getLocale(ULocale.Type type) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Standard override.
-     * @stable ICU 2.0
-     */
-    public Object clone() {
-        return new DecimalFormatSymbols((java.text.DecimalFormatSymbols)dfs.clone());
-    }
-        
-    /**
-     * Override equals.
-     * @stable ICU 2.0
-     */
-    public boolean equals(Object obj) {
-        try {
-            return dfs.equals(((DecimalFormatSymbols)obj).dfs);
-        }
-        catch (Exception e) {
-            return false;
-        }
-    }
-        
-    /**
-     * Override hashCode
-     * @stable ICU 2.0
-     */
-    public int hashCode() {
-        return dfs.hashCode();
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/MessageFormat.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/MessageFormat.java
deleted file mode 100644
index a2db295..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/MessageFormat.java
+++ /dev/null
@@ -1,1455 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
-**********************************************************************
-* Copyright (c) 2004-2012, International Business Machines
-* Corporation and others.  All Rights Reserved.
-**********************************************************************
-* Author: Alan Liu
-* Created: April 6, 2004
-* Since: ICU 3.0
-**********************************************************************
-*/
-package com.ibm.icu.text;
-
-import java.io.InvalidObjectException;
-import java.text.AttributedCharacterIterator;
-import java.text.AttributedCharacterIterator.Attribute;
-import java.text.AttributedString;
-import java.text.CharacterIterator;
-import java.text.ChoiceFormat;
-import java.text.FieldPosition;
-import java.text.Format;
-import java.text.ParseException;
-import java.text.ParsePosition;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import com.ibm.icu.util.ULocale;
-import com.ibm.icu.util.ULocale.Category;
-
-/**
- * {@icuenhanced java.text.MessageFormat}.{@icu _usage_}
- *
- * <p>MessageFormat produces concatenated messages in a language-neutral
- * way. Use this whenever concatenating strings that are displayed to
- * end users.
- *
- * <p>A MessageFormat contains an array of <em>subformats</em> arranged
- * within a <em>template string</em>.  Together, the subformats and
- * template string determine how the MessageFormat will operate during
- * formatting and parsing.
- *
- * <p>Typically, both the subformats and the template string are
- * specified at once in a <em>pattern</em>.  By using different
- * patterns for different locales, messages may be localized.
- *
- * <p>When formatting, MessageFormat takes a collection of arguments
- * and produces a user-readable string.  The arguments may be passed
- * as an array or as a Map.  Each argument is matched up with its
- * corresponding subformat, which then formats it into a string.  The
- * resulting strings are then assembled within the string template of
- * the MessageFormat to produce the final output string.
- *
- * <p><strong>Note:</strong>
- * <code>MessageFormat</code> differs from the other <code>Format</code>
- * classes in that you create a <code>MessageFormat</code> object with one
- * of its constructors (not with a <code>getInstance</code> style factory
- * method). The factory methods aren't necessary because <code>MessageFormat</code>
- * itself doesn't implement locale-specific behavior. Any locale-specific
- * behavior is defined by the pattern that you provide and the
- * subformats used for inserted arguments.
- *
- * <p><strong>Note:</strong>
- * In ICU 3.8 MessageFormat supports named arguments.  If a named argument
- * is used, all arguments must be named.  Names start with a character in
- * <code>:ID_START:</code> and continue with characters in <code>:ID_CONTINUE:</code>,
- * in particular they do not start with a digit.  If named arguments
- * are used, {@link #usesNamedArguments()} will return true.
- *
- * <p>The other new methods supporting named arguments are
- * {@link #setFormatsByArgumentName(Map)},
- * {@link #setFormatByArgumentName(String, Format)},
- * {@link #format(Map, StringBuffer, FieldPosition)},
- * {@link #format(String, Map)}, {@link #parseToMap(String, ParsePosition)},
- * and {@link #parseToMap(String)}.  These methods are all compatible
- * with patterns that do not used named arguments-- in these cases
- * the keys in the input or output <code>Map</code>s use
- * <code>String</code>s that name the argument indices, e.g. "0",
- * "1", "2"... etc.
- *
- * <p>When named arguments are used, certain methods on MessageFormat that take or
- * return arrays will throw an exception, since it is not possible to
- * identify positions in an array using a name.  These methods are
- * {@link #setFormatsByArgumentIndex(Format[])},
- * {@link #setFormatByArgumentIndex(int, Format)},
- * {@link #getFormatsByArgumentIndex()},
- * {@link #getFormats()},
- * {@link #format(Object[], StringBuffer, FieldPosition)},
- * {@link #format(String, Object[])},
- * {@link #parse(String, ParsePosition)}, and
- * {@link #parse(String)}.
- * These APIs all have corresponding new versions as listed above.
- *
- * <p>The API {@link #format(Object, StringBuffer, FieldPosition)} has
- * been modified so that the <code>Object</code> argument can be
- * either an <code>Object</code> array or a <code>Map</code>.  If this
- * format uses named arguments, this argument must not be an
- * <code>Object</code> array otherwise an exception will be thrown.
- * If the argument is a <code>Map</code> it can be used with Strings that
- * represent indices as described above.
- *
- * <h4><a name="patterns">Patterns and Their Interpretation</a></h4>
- *
- * <code>MessageFormat</code> uses patterns of the following form:
- * <blockquote><pre>
- * <i>MessageFormatPattern:</i>
- *         <i>String</i>
- *         <i>MessageFormatPattern</i> <i>FormatElement</i> <i>String</i>
- *
- * <i>FormatElement:</i>
- *         { <i>ArgumentIndexOrName</i> }
- *         { <i>ArgumentIndexOrName</i> , <i>FormatType</i> }
- *         { <i>ArgumentIndexOrName</i> , <i>FormatType</i> , <i>FormatStyle</i> }
- *
- * <i>ArgumentIndexOrName: one of </i>
- *         ['0'-'9']+
- *         [:ID_START:][:ID_CONTINUE:]*
- *
- * <i>FormatType: one of </i>
- *         number date time choice spellout ordinal duration plural
- *
- * <i>FormatStyle:</i>
- *         short
- *         medium
- *         long
- *         full
- *         integer
- *         currency
- *         percent
- *         <i>SubformatPattern</i>
- *         <i>RulesetName</i>
- *
- * <i>String:</i>
- *         <i>StringPart<sub>opt</sub></i>
- *         <i>String</i> <i>StringPart</i>
- *
- * <i>StringPart:</i>
- *         ''
- *         ' <i>QuotedString</i> '
- *         <i>UnquotedString</i>
- *
- * <i>SubformatPattern:</i>
- *         <i>SubformatPatternPart<sub>opt</sub></i>
- *         <i>SubformatPattern</i> <i>SubformatPatternPart</i>
- *
- * <i>SubFormatPatternPart:</i>
- *         ' <i>QuotedPattern</i> '
- *         <i>UnquotedPattern</i>
- * </pre></blockquote>
- *
- * <i>RulesetName:</i>
- *         <i>UnquotedString</i>
- *
- * <p>Within a <i>String</i>, <code>"''"</code> represents a single
- * quote. A <i>QuotedString</i> can contain arbitrary characters
- * except single quotes; the surrounding single quotes are removed.
- * An <i>UnquotedString</i> can contain arbitrary characters
- * except single quotes and left curly brackets. Thus, a string that
- * should result in the formatted message "'{0}'" can be written as
- * <code>"'''{'0}''"</code> or <code>"'''{0}'''"</code>.
- *
- * <p>Within a <i>SubformatPattern</i>, different rules apply.
- * A <i>QuotedPattern</i> can contain arbitrary characters
- * except single quotes; but the surrounding single quotes are
- * <strong>not</strong> removed, so they may be interpreted by the
- * subformat. For example, <code>"{1,number,$'#',##}"</code> will
- * produce a number format with the pound-sign quoted, with a result
- * such as: "$#31,45".
- * An <i>UnquotedPattern</i> can contain arbitrary characters
- * except single quotes, but curly braces within it must be balanced.
- * For example, <code>"ab {0} de"</code> and <code>"ab '}' de"</code>
- * are valid subformat patterns, but <code>"ab {0'}' de"</code> and
- * <code>"ab } de"</code> are not.
- *
- * <p><dl><dt><b>Warning:</b><dd>The rules for using quotes within message
- * format patterns unfortunately have shown to be somewhat confusing.
- * In particular, it isn't always obvious to localizers whether single
- * quotes need to be doubled or not. Make sure to inform localizers about
- * the rules, and tell them (for example, by using comments in resource
- * bundle source files) which strings will be processed by MessageFormat.
- * Note that localizers may need to use single quotes in translated
- * strings where the original version doesn't have them.
- *
- * <br>Note also that the simplest way to avoid the problem is to
- * use the real apostrophe (single quote) character \u2019 (') for
- * human-readable text, and to use the ASCII apostrophe (\u0027 ' )
- * only in program syntax, like quoting in MessageFormat.
- * See the annotations for U+0027 Apostrophe in The Unicode Standard.</p>
- * </dl>
- *
- * <p>The <i>ArgumentIndex</i> value is a non-negative integer written
- * using the digits '0' through '9', and represents an index into the
- * <code>arguments</code> array passed to the <code>format</code> methods
- * or the result array returned by the <code>parse</code> methods.
- *
- * <p>The <i>FormatType</i> and <i>FormatStyle</i> values are used to create
- * a <code>Format</code> instance for the format element. The following
- * table shows how the values map to Format instances. Combinations not
- * shown in the table are illegal. A <i>SubformatPattern</i> must
- * be a valid pattern string for the Format subclass used.
- *
- * <p><table border=1>
- *    <tr>
- *       <th>Format Type
- *       <th>Format Style
- *       <th>Subformat Created
- *    <tr>
- *       <td colspan=2><i>(none)</i>
- *       <td><code>null</code>
- *    <tr>
- *       <td rowspan=5><code>number</code>
- *       <td><i>(none)</i>
- *       <td><code>NumberFormat.getInstance(getLocale())</code>
- *    <tr>
- *       <td><code>integer</code>
- *       <td><code>NumberFormat.getIntegerInstance(getLocale())</code>
- *    <tr>
- *       <td><code>currency</code>
- *       <td><code>NumberFormat.getCurrencyInstance(getLocale())</code>
- *    <tr>
- *       <td><code>percent</code>
- *       <td><code>NumberFormat.getPercentInstance(getLocale())</code>
- *    <tr>
- *       <td><i>SubformatPattern</i>
- *       <td><code>new DecimalFormat(subformatPattern, new DecimalFormatSymbols(getLocale()))</code>
- *    <tr>
- *       <td rowspan=6><code>date</code>
- *       <td><i>(none)</i>
- *       <td><code>DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())</code>
- *    <tr>
- *       <td><code>short</code>
- *       <td><code>DateFormat.getDateInstance(DateFormat.SHORT, getLocale())</code>
- *    <tr>
- *       <td><code>medium</code>
- *       <td><code>DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())</code>
- *    <tr>
- *       <td><code>long</code>
- *       <td><code>DateFormat.getDateInstance(DateFormat.LONG, getLocale())</code>
- *    <tr>
- *       <td><code>full</code>
- *       <td><code>DateFormat.getDateInstance(DateFormat.FULL, getLocale())</code>
- *    <tr>
- *       <td><i>SubformatPattern</i>
- *       <td><code>new SimpleDateFormat(subformatPattern, getLocale())
- *    <tr>
- *       <td rowspan=6><code>time</code>
- *       <td><i>(none)</i>
- *       <td><code>DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())</code>
- *    <tr>
- *       <td><code>short</code>
- *       <td><code>DateFormat.getTimeInstance(DateFormat.SHORT, getLocale())</code>
- *    <tr>
- *       <td><code>medium</code>
- *       <td><code>DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())</code>
- *    <tr>
- *       <td><code>long</code>
- *       <td><code>DateFormat.getTimeInstance(DateFormat.LONG, getLocale())</code>
- *    <tr>
- *       <td><code>full</code>
- *       <td><code>DateFormat.getTimeInstance(DateFormat.FULL, getLocale())</code>
- *    <tr>
- *       <td><i>SubformatPattern</i>
- *       <td><code>new SimpleDateFormat(subformatPattern, getLocale())
- *    <tr>
- *       <td><code>choice</code>
- *       <td><i>SubformatPattern</i>
- *       <td><code>new ChoiceFormat(subformatPattern)</code>
- *    <tr>
- *       <td><code>spellout</code>
- *       <td><i>RulesetName (optional)</i>
- *       <td><code>new RuleBasedNumberFormat(getLocale(), RuleBasedNumberFormat.SPELLOUT)
- *           <br/>&nbsp;&nbsp;&nbsp;&nbsp;.setDefaultRuleset(ruleset);</code>
- *    <tr>
- *       <td><code>ordinal</code>
- *       <td><i>RulesetName (optional)</i>
- *       <td><code>new RuleBasedNumberFormat(getLocale(), RuleBasedNumberFormat.ORDINAL)
- *           <br/>&nbsp;&nbsp;&nbsp;&nbsp;.setDefaultRuleset(ruleset);</code>
- *    <tr>
- *       <td><code>duration</code>
- *       <td><i>RulesetName (optional)</i>
- *       <td><code>new RuleBasedNumberFormat(getLocale(), RuleBasedNumberFormat.DURATION)
- *           <br/>&nbsp;&nbsp;&nbsp;&nbsp;.setDefaultRuleset(ruleset);</code>
- *    <tr>
- *       <td><code>plural</code>
- *       <td><i>SubformatPattern</i>
- *       <td><code>new PluralFormat(subformatPattern)</code>
- *    <tr>
- *       <td><code>select</code>
- *       <td><i>SubformatPattern</i>
- *       <td><code>new SelectFormat(subformatPattern)</code>
- * </table>
- * <p>
- *
- * <h4>Usage Information</h4>
- *
- * <p>Here are some examples of usage:
- * <blockquote>
- * <pre>
- * Object[] arguments = {
- *     new Integer(7),
- *     new Date(System.currentTimeMillis()),
- *     "a disturbance in the Force"
- * };
- *
- * String result = MessageFormat.format(
- *     "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
- *     arguments);
- *
- * <em>output</em>: At 12:30 PM on Jul 3, 2053, there was a disturbance
- *           in the Force on planet 7.
- *
- * </pre>
- * </blockquote>
- * Typically, the message format will come from resources, and the
- * arguments will be dynamically set at runtime.
- *
- * <p>Example 2:
- * <blockquote>
- * <pre>
- * Object[] testArgs = {new Long(3), "MyDisk"};
- *
- * MessageFormat form = new MessageFormat(
- *     "The disk \"{1}\" contains {0} file(s).");
- *
- * System.out.println(form.format(testArgs));
- *
- * // output, with different testArgs
- * <em>output</em>: The disk "MyDisk" contains 0 file(s).
- * <em>output</em>: The disk "MyDisk" contains 1 file(s).
- * <em>output</em>: The disk "MyDisk" contains 1,273 file(s).
- * </pre>
- * </blockquote>
- *
- * <p>For more sophisticated patterns, you can use a <code>ChoiceFormat</code> to get
- * output such as:
- * <blockquote>
- * <pre>
- * MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0}.");
- * double[] filelimits = {0,1,2};
- * String[] filepart = {"no files","one file","{0,number} files"};
- * ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
- * form.setFormatByArgumentIndex(0, fileform);
- *
- * Object[] testArgs = {new Long(12373), "MyDisk"};
- *
- * System.out.println(form.format(testArgs));
- *
- * // output, with different testArgs
- * output: The disk "MyDisk" contains no files.
- * output: The disk "MyDisk" contains one file.
- * output: The disk "MyDisk" contains 1,273 files.
- * </pre>
- * </blockquote>
- * You can either do this programmatically, as in the above example,
- * or by using a pattern (see
- * {@link ChoiceFormat}
- * for more information) as in:
- * <blockquote>
- * <pre>
- * form.applyPattern(
- *    "There {0,choice,0#are no files|1#is one file|1&lt;are {0,number,integer} files}.");
- * </pre>
- * </blockquote>
- *
- * <p><strong>Note:</strong> As we see above, the string produced
- * by a <code>ChoiceFormat</code> in <code>MessageFormat</code> is treated specially;
- * occurances of '{' are used to indicated subformats, and cause recursion.
- * If you create both a <code>MessageFormat</code> and <code>ChoiceFormat</code>
- * programmatically (instead of using the string patterns), then be careful not to
- * produce a format that recurses on itself, which will cause an infinite loop.
- *
- * <p>When a single argument is parsed more than once in the string, the last match
- * will be the final result of the parsing.  For example,
- * <pre>
- * MessageFormat mf = new MessageFormat("{0,number,#.##}, {0,number,#.#}");
- * Object[] objs = {new Double(3.1415)};
- * String result = mf.format( objs );
- * // result now equals "3.14, 3.1"
- * objs = null;
- * objs = mf.parse(result, new ParsePosition(0));
- * // objs now equals {new Double(3.1)}
- * </pre>
- *
- * <p>Likewise, parsing with a MessageFormat object using patterns containing
- * multiple occurances of the same argument would return the last match.  For
- * example,
- * <pre>
- * MessageFormat mf = new MessageFormat("{0}, {0}, {0}");
- * String forParsing = "x, y, z";
- * Object[] objs = mf.parse(forParsing, new ParsePosition(0));
- * // result now equals {new String("z")}
- * </pre>
- *
- * <h4><a name="synchronization">Synchronization</a></h4>
- *
- * <p>Message formats are not synchronized.
- * It is recommended to create separate format instances for each thread.
- * If multiple threads access a format concurrently, it must be synchronized
- * externally.
- *
- * @see          java.util.Locale
- * @see          Format
- * @see          NumberFormat
- * @see          DecimalFormat
- * @see          ChoiceFormat
- * @see          PluralFormat
- * @see          SelectFormat
- * @author       Mark Davis
- * @stable ICU 3.0
- */
-public class MessageFormat extends UFormat {
-    static final long serialVersionUID = 1L;
-
-    /**
-     * @internal
-     */
-    public final java.text.MessageFormat messageFormat;
-        
-    /**
-     * @internal
-     * @param delegate the DateFormat to which to delegate
-     */
-    public MessageFormat(java.text.MessageFormat delegate) {
-        wrapNestedFormatters(delegate);
-        this.messageFormat = delegate;
-    }
-
-    /**
-     * Constructs a MessageFormat for the default locale and the
-     * specified pattern.
-     * The constructor first sets the locale, then parses the pattern and
-     * creates a list of subformats for the format elements contained in it.
-     * Patterns and their interpretation are specified in the
-     * <a href="#patterns">class description</a>.
-     *
-     * @param pattern the pattern for this message format
-     * @exception IllegalArgumentException if the pattern is invalid
-     * @stable ICU 3.0
-     */
-    public MessageFormat(String pattern) {
-        this(new java.text.MessageFormat(pattern, ULocale.getDefault(Category.FORMAT).toLocale()));
-    }
-
-    /**
-     * Constructs a MessageFormat for the specified locale and
-     * pattern.
-     * The constructor first sets the locale, then parses the pattern and
-     * creates a list of subformats for the format elements contained in it.
-     * Patterns and their interpretation are specified in the
-     * <a href="#patterns">class description</a>.
-     *
-     * @param pattern the pattern for this message format
-     * @param locale the locale for this message format
-     * @exception IllegalArgumentException if the pattern is invalid
-     * @stable ICU 3.0
-     */
-    public MessageFormat(String pattern, Locale locale) {
-        this(new java.text.MessageFormat(pattern, locale));
-    }
-
-    /**
-     * Constructs a MessageFormat for the specified locale and
-     * pattern.
-     * The constructor first sets the locale, then parses the pattern and
-     * creates a list of subformats for the format elements contained in it.
-     * Patterns and their interpretation are specified in the
-     * <a href="#patterns">class description</a>.
-     *
-     * @param pattern the pattern for this message format
-     * @param locale the locale for this message format
-     * @exception IllegalArgumentException if the pattern is invalid
-     * @stable ICU 3.2
-     */
-    public MessageFormat(String pattern, ULocale locale) {
-        this(new java.text.MessageFormat(pattern, locale.toLocale()));
-    }
-
-    /**
-     * Sets the locale to be used when creating or comparing subformats.
-     * This affects subsequent calls to the {@link #applyPattern applyPattern}
-     * and {@link #toPattern toPattern} methods as well as to the
-     * <code>format</code> and
-     * {@link #formatToCharacterIterator formatToCharacterIterator} methods.
-     *
-     * @param locale the locale to be used when creating or comparing subformats
-     * @stable ICU 3.0
-     */
-    public void setLocale(Locale locale) {
-        messageFormat.setLocale(locale);
-    }
-
-    /**
-     * Sets the locale to be used when creating or comparing subformats.
-     * This affects subsequent calls to the {@link #applyPattern applyPattern}
-     * and {@link #toPattern toPattern} methods as well as to the
-     * <code>format</code> and
-     * {@link #formatToCharacterIterator formatToCharacterIterator} methods.
-     *
-     * @param locale the locale to be used when creating or comparing subformats
-     * @stable ICU 3.2
-     */
-    public void setLocale(ULocale locale) {
-        messageFormat.setLocale(locale.toLocale());
-    }
-
-    /**
-     * Returns the locale that's used when creating or comparing subformats.
-     *
-     * @return the locale used when creating or comparing subformats
-     * @stable ICU 3.0
-     */
-    public Locale getLocale() {
-        return messageFormat.getLocale();
-    }
-
-    /**
-     * {@icu} Returns the locale that's used when creating or comparing subformats.
-     *
-     * @return the locale used when creating or comparing subformats
-     * @stable ICU 3.2
-     */
-    public ULocale getULocale() {
-        return ULocale.forLocale(messageFormat.getLocale());
-    }
-
-    /**
-     * Sets the pattern used by this message format.
-     * The method parses the pattern and creates a list of subformats
-     * for the format elements contained in it.
-     * Patterns and their interpretation are specified in the
-     * <a href="#patterns">class description</a>.
-     * <p>
-     * The pattern must contain only named or only numeric arguments,
-     * mixing them is not allowed.
-     *
-     * @param pttrn the pattern for this message format
-     * @throws IllegalArgumentException if the pattern is invalid
-     * @stable ICU 3.0
-     */
-    public void applyPattern(String pttrn) {
-        messageFormat.applyPattern(pttrn);
-        wrapNestedFormatters(messageFormat);
-    }
-
-//    /**
-//     * {@icu} Sets the ApostropheMode and the pattern used by this message format.
-//     * Parses the pattern and caches Format objects for simple argument types.
-//     * Patterns and their interpretation are specified in the
-//     * <a href="#patterns">class description</a>.
-//     * <p>
-//     * This method is best used only once on a given object to avoid confusion about the mode,
-//     * and after constructing the object with an empty pattern string to minimize overhead.
-//     *
-//     * @param pattern the pattern for this message format
-//     * @param aposMode the new ApostropheMode
-//     * @throws IllegalArgumentException if the pattern is invalid
-//     * @see MessagePattern.ApostropheMode
-//     * @stable ICU 4.8
-//     */
-//    public void applyPattern(String pattern, MessagePattern.ApostropheMode aposMode) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu}
-//     * @return this instance's ApostropheMode.
-//     * @stable ICU 4.8
-//     */
-//    public MessagePattern.ApostropheMode getApostropheMode() {
-//    	throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Returns a pattern representing the current state of the message format.
-     * The string is constructed from internal information and therefore
-     * does not necessarily equal the previously applied pattern.
-     *
-     * @return a pattern representing the current state of the message format
-     * @stable ICU 3.0
-     */
-    public String toPattern() {
-        String pattern = savedPattern == null ? messageFormat.toPattern() : savedPattern;
-        return pattern;
-    }
-
-    /**
-     * Sets the formats to use for the values passed into
-     * <code>format</code> methods or returned from <code>parse</code>
-     * methods. The indices of elements in <code>newFormats</code>
-     * correspond to the argument indices used in the previously set
-     * pattern string.
-     * The order of formats in <code>newFormats</code> thus corresponds to
-     * the order of elements in the <code>arguments</code> array passed
-     * to the <code>format</code> methods or the result array returned
-     * by the <code>parse</code> methods.
-     * <p>
-     * If an argument index is used for more than one format element
-     * in the pattern string, then the corresponding new format is used
-     * for all such format elements. If an argument index is not used
-     * for any format element in the pattern string, then the
-     * corresponding new format is ignored. If fewer formats are provided
-     * than needed, then only the formats for argument indices less
-     * than <code>newFormats.length</code> are replaced.
-     *
-     * This method is only supported if the format does not use
-     * named arguments, otherwise an IllegalArgumentException is thrown.
-     *
-     * @param newFormats the new formats to use
-     * @throws NullPointerException if <code>newFormats</code> is null
-     * @throws IllegalArgumentException if this formatter uses named arguments
-     * @stable ICU 3.0
-     */
-    public void setFormatsByArgumentIndex(Format[] newFormats) {
-        messageFormat.setFormatsByArgumentIndex(newFormats);
-        savedPattern = null;
-    }
-
-//    /**
-//     * {@icu} Sets the formats to use for the values passed into
-//     * <code>format</code> methods or returned from <code>parse</code>
-//     * methods. The keys in <code>newFormats</code> are the argument
-//     * names in the previously set pattern string, and the values
-//     * are the formats.
-//     * <p>
-//     * Only argument names from the pattern string are considered.
-//     * Extra keys in <code>newFormats</code> that do not correspond
-//     * to an argument name are ignored.  Similarly, if there is no
-//     * format in newFormats for an argument name, the formatter
-//     * for that argument remains unchanged.
-//     * <p>
-//     * This may be called on formats that do not use named arguments.
-//     * In this case the map will be queried for key Strings that
-//     * represent argument indices, e.g. "0", "1", "2" etc.
-//     *
-//     * @param newFormats a map from String to Format providing new
-//     *        formats for named arguments.
-//     * @stable ICU 3.8
-//     */
-//    public void setFormatsByArgumentName(Map<String, Format> newFormats) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Sets the formats to use for the format elements in the
-     * previously set pattern string.
-     * The order of formats in <code>newFormats</code> corresponds to
-     * the order of format elements in the pattern string.
-     * <p>
-     * If more formats are provided than needed by the pattern string,
-     * the remaining ones are ignored. If fewer formats are provided
-     * than needed, then only the first <code>newFormats.length</code>
-     * formats are replaced.
-     * <p>
-     * Since the order of format elements in a pattern string often
-     * changes during localization, it is generally better to use the
-     * {@link #setFormatsByArgumentIndex setFormatsByArgumentIndex}
-     * method, which assumes an order of formats corresponding to the
-     * order of elements in the <code>arguments</code> array passed to
-     * the <code>format</code> methods or the result array returned by
-     * the <code>parse</code> methods.
-     *
-     * @param newFormats the new formats to use
-     * @exception NullPointerException if <code>newFormats</code> is null
-     * @stable ICU 3.0
-     */
-    public void setFormats(Format[] newFormats) {
-        messageFormat.setFormats(newFormats);
-        savedPattern = null;
-    }
-
-    /**
-     * Sets the format to use for the format elements within the
-     * previously set pattern string that use the given argument
-     * index.
-     * The argument index is part of the format element definition and
-     * represents an index into the <code>arguments</code> array passed
-     * to the <code>format</code> methods or the result array returned
-     * by the <code>parse</code> methods.
-     * <p>
-     * If the argument index is used for more than one format element
-     * in the pattern string, then the new format is used for all such
-     * format elements. If the argument index is not used for any format
-     * element in the pattern string, then the new format is ignored.
-     *
-     * This method is only supported when exclusively numbers are used for
-     * argument names. Otherwise an IllegalArgumentException is thrown.
-     *
-     * @param argumentIndex the argument index for which to use the new format
-     * @param newFormat the new format to use
-     * @throws IllegalArgumentException if this format uses named arguments
-     * @stable ICU 3.0
-     */
-    public void setFormatByArgumentIndex(int argumentIndex, Format newFormat) {
-        messageFormat.setFormatByArgumentIndex(argumentIndex, newFormat);
-        savedPattern = null;
-    }
-
-//    /**
-//     * {@icu} Sets the format to use for the format elements within the
-//     * previously set pattern string that use the given argument
-//     * name.
-//     * <p>
-//     * If the argument name is used for more than one format element
-//     * in the pattern string, then the new format is used for all such
-//     * format elements. If the argument name is not used for any format
-//     * element in the pattern string, then the new format is ignored.
-//     * <p>
-//     * This API may be used on formats that do not use named arguments.
-//     * In this case <code>argumentName</code> should be a String that names
-//     * an argument index, e.g. "0", "1", "2"... etc.  If it does not name
-//     * a valid index, the format will be ignored.  No error is thrown.
-//     *
-//     * @param argumentName the name of the argument to change
-//     * @param newFormat the new format to use
-//     * @stable ICU 3.8
-//     */
-//    public void setFormatByArgumentName(String argumentName, Format newFormat) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Sets the format to use for the format element with the given
-     * format element index within the previously set pattern string.
-     * The format element index is the zero-based number of the format
-     * element counting from the start of the pattern string.
-     * <p>
-     * Since the order of format elements in a pattern string often
-     * changes during localization, it is generally better to use the
-     * {@link #setFormatByArgumentIndex setFormatByArgumentIndex}
-     * method, which accesses format elements based on the argument
-     * index they specify.
-     *
-     * @param formatElementIndex the index of a format element within the pattern
-     * @param newFormat the format to use for the specified format element
-     * @exception ArrayIndexOutOfBoundsException if formatElementIndex is equal to or
-     *            larger than the number of format elements in the pattern string
-     * @stable ICU 3.0
-     */
-    public void setFormat(int formatElementIndex, Format newFormat) {
-        messageFormat.setFormat(formatElementIndex, newFormat);
-        savedPattern = null;
-    }
-
-    /**
-     * Returns the formats used for the values passed into
-     * <code>format</code> methods or returned from <code>parse</code>
-     * methods. The indices of elements in the returned array
-     * correspond to the argument indices used in the previously set
-     * pattern string.
-     * The order of formats in the returned array thus corresponds to
-     * the order of elements in the <code>arguments</code> array passed
-     * to the <code>format</code> methods or the result array returned
-     * by the <code>parse</code> methods.
-     * <p>
-     * If an argument index is used for more than one format element
-     * in the pattern string, then the format used for the last such
-     * format element is returned in the array. If an argument index
-     * is not used for any format element in the pattern string, then
-     * null is returned in the array.
-     *
-     * This method is only supported when exclusively numbers are used for
-     * argument names. Otherwise an IllegalArgumentException is thrown.
-     *
-     * @return the formats used for the arguments within the pattern
-     * @throws IllegalArgumentException if this format uses named arguments
-     * @stable ICU 3.0
-     */
-    public Format[] getFormatsByArgumentIndex() {
-        return messageFormat.getFormatsByArgumentIndex();
-    }
-
-    /**
-     * Returns the formats used for the format elements in the
-     * previously set pattern string.
-     * The order of formats in the returned array corresponds to
-     * the order of format elements in the pattern string.
-     * <p>
-     * Since the order of format elements in a pattern string often
-     * changes during localization, it's generally better to use the
-     * {@link #getFormatsByArgumentIndex()}
-     * method, which assumes an order of formats corresponding to the
-     * order of elements in the <code>arguments</code> array passed to
-     * the <code>format</code> methods or the result array returned by
-     * the <code>parse</code> methods.
-     *
-     * This method is only supported when exclusively numbers are used for
-     * argument names. Otherwise an IllegalArgumentException is thrown.
-     *
-     * @return the formats used for the format elements in the pattern
-     * @throws IllegalArgumentException if this format uses named arguments
-     * @stable ICU 3.0
-     */
-    public Format[] getFormats() {
-        return messageFormat.getFormats();
-    }
-
-//    /**
-//     * {@icu} Returns the format argument names. For more details, see
-//     * {@link #setFormatByArgumentName(String, Format)}.
-//     * @return List of names
-//     * @internal
-//     * @deprecated This API is ICU internal only.
-//     */
-//    public Set<String> getFormatArgumentNames() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the first top-level format associated with the given argument name.
-//     * For more details, see {@link #setFormatByArgumentName(String, Format)}.
-//     * @param argumentName The name of the desired argument.
-//     * @return the Format associated with the name, or null if there isn't one.
-//     * @stable ICU 4.8
-//     */
-//    public Format getFormatByArgumentName(String argumentName) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the top-level argument names. For more details, see
-//     * {@link #setFormatByArgumentName(String, Format)}.
-//     * @return a Set of argument names
-//     * @stable ICU 4.8
-//     */
-//    public Set<String> getArgumentNames() {
-//    	throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-    
-    /**
-     * Formats an array of objects and appends the <code>MessageFormat</code>'s
-     * pattern, with format elements replaced by the formatted objects, to the
-     * provided <code>StringBuffer</code>.
-     * <p>
-     * The text substituted for the individual format elements is derived from
-     * the current subformat of the format element and the
-     * <code>arguments</code> element at the format element's argument index
-     * as indicated by the first matching line of the following table. An
-     * argument is <i>unavailable</i> if <code>arguments</code> is
-     * <code>null</code> or has fewer than argumentIndex+1 elements.  When
-     * an argument is unavailable no substitution is performed.
-     * <p>
-     * <table border=1>
-     *    <tr>
-     *       <th>Subformat
-     *       <th>Argument
-     *       <th>Formatted Text
-     *    <tr>
-     *       <td><i>any</i>
-     *       <td><i>unavailable</i>
-     *       <td><code>"{" + argumentIndex + "}"</code>
-     *    <tr>
-     *       <td><i>any</i>
-     *       <td><code>null</code>
-     *       <td><code>"null"</code>
-     *    <tr>
-     *       <td><code>instanceof ChoiceFormat</code>
-     *       <td><i>any</i>
-     *       <td><code>subformat.format(argument).indexOf('{') >= 0 ?<br>
-     *           (new MessageFormat(subformat.format(argument), getLocale())).format(argument) :
-     *           subformat.format(argument)</code>
-     *    <tr>
-     *       <td><code>!= null</code>
-     *       <td><i>any</i>
-     *       <td><code>subformat.format(argument)</code>
-     *    <tr>
-     *       <td><code>null</code>
-     *       <td><code>instanceof Number</code>
-     *       <td><code>NumberFormat.getInstance(getLocale()).format(argument)</code>
-     *    <tr>
-     *       <td><code>null</code>
-     *       <td><code>instanceof Date</code>
-     *       <td><code>DateFormat.getDateTimeInstance(DateFormat.SHORT,
-     *           DateFormat.SHORT, getLocale()).format(argument)</code>
-     *    <tr>
-     *       <td><code>null</code>
-     *       <td><code>instanceof String</code>
-     *       <td><code>argument</code>
-     *    <tr>
-     *       <td><code>null</code>
-     *       <td><i>any</i>
-     *       <td><code>argument.toString()</code>
-     * </table>
-     * <p>
-     * If <code>pos</code> is non-null, and refers to
-     * <code>Field.ARGUMENT</code>, the location of the first formatted
-     * string will be returned.
-     *
-     * This method is only supported when the format does not use named
-     * arguments, otherwise an IllegalArgumentException is thrown.
-     *
-     * @param arguments an array of objects to be formatted and substituted.
-     * @param result where text is appended.
-     * @param pos On input: an alignment field, if desired.
-     *            On output: the offsets of the alignment field.
-     * @throws IllegalArgumentException if an argument in the
-     *            <code>arguments</code> array is not of the type
-     *            expected by the format element(s) that use it.
-     * @throws IllegalArgumentException if this format uses named arguments
-     * @stable ICU 3.0
-     */
-    public final StringBuffer format(Object[] arguments, StringBuffer result,
-                                     FieldPosition pos) {
-        FieldPosition jdkPos = toJDKFieldPosition(pos);
-        StringBuffer buf = messageFormat.format(arguments, result, jdkPos);
-        if (jdkPos != null) {
-            pos.setBeginIndex(jdkPos.getBeginIndex());
-            pos.setEndIndex(jdkPos.getEndIndex());
-        }
-        return buf;
-    }
-
-//    /**
-//     * Formats a map of objects and appends the <code>MessageFormat</code>'s
-//     * pattern, with format elements replaced by the formatted objects, to the
-//     * provided <code>StringBuffer</code>.
-//     * <p>
-//     * The text substituted for the individual format elements is derived from
-//     * the current subformat of the format element and the
-//     * <code>arguments</code> value corresponding to the format element's
-//     * argument name.
-//     * <p>
-//     * This API may be called on formats that do not use named arguments.
-//     * In this case the the keys in <code>arguments</code> must be numeric
-//     * strings (e.g. "0", "1", "2"...).
-//     * <p>
-//     * An argument is <i>unavailable</i> if <code>arguments</code> is
-//     * <code>null</code> or does not have a value corresponding to an argument
-//     * name in the pattern.  When an argument is unavailable no substitution
-//     * is performed.
-//     *
-//     * @param arguments a map of objects to be formatted and substituted.
-//     * @param result where text is appended.
-//     * @param pos On input: an alignment field, if desired.
-//     *            On output: the offsets of the alignment field.
-//     * @throws IllegalArgumentException if an argument in the
-//     *         <code>arguments</code> array is not of the type
-//     *         expected by the format element(s) that use it.
-//     * @return the passed-in StringBuffer
-//     * @stable ICU 3.8
-//     */
-//    public final StringBuffer format(Map<String, Object> arguments, StringBuffer result,
-//                                     FieldPosition pos) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Creates a MessageFormat with the given pattern and uses it
-     * to format the given arguments. This is equivalent to
-     * <blockquote>
-     *     <code>(new {@link #MessageFormat(String) MessageFormat}(pattern)).{@link
-     *     #format(java.lang.Object[], java.lang.StringBuffer, java.text.FieldPosition)
-     *     format}(arguments, new StringBuffer(), null).toString()</code>
-     * </blockquote>
-     *
-     * @throws IllegalArgumentException if the pattern is invalid,
-     *            or if an argument in the <code>arguments</code> array
-     *            is not of the type expected by the format element(s)
-     *            that use it.
-     * @throws IllegalArgumentException if this format uses named arguments
-     * @stable ICU 3.0
-     */
-    public static String format(String pattern, Object... arguments) {
-        return java.text.MessageFormat.format(pattern, arguments);
-    }
-
-//    /**
-//     * Creates a MessageFormat with the given pattern and uses it to
-//     * format the given arguments.  The pattern must identifyarguments
-//     * by name instead of by number.
-//     * <p>
-//     * @throws IllegalArgumentException if the pattern is invalid,
-//     *         or if an argument in the <code>arguments</code> map
-//     *         is not of the type expected by the format element(s)
-//     *         that use it.
-//     * @see #format(Map, StringBuffer, FieldPosition)
-//     * @see #format(String, Object[])
-//     * @stable ICU 3.8
-//     */
-//    public static String format(String pattern, Map<String, Object> arguments) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * {@icu} Returns true if this MessageFormat uses named arguments,
-     * and false otherwise.  See class description.
-     *
-     * @return true if named arguments are used.
-     * @stable ICU 3.8
-     */
-    public boolean usesNamedArguments() {
-        // always false with com.ibm.icu.base
-        return false;
-    }
-
-    // Overrides
-    /**
-     * Formats a map or array of objects and appends the <code>MessageFormat</code>'s
-     * pattern, with format elements replaced by the formatted objects, to the
-     * provided <code>StringBuffer</code>.
-     * This is equivalent to either of
-     * <blockquote>
-     *     <code>{@link #format(java.lang.Object[], java.lang.StringBuffer,
-     *     java.text.FieldPosition) format}((Object[]) arguments, result, pos)</code>
-     *     <code>{@link #format(java.util.Map, java.lang.StringBuffer,
-     *     java.text.FieldPosition) format}((Map) arguments, result, pos)</code>
-     * </blockquote>
-     * A map must be provided if this format uses named arguments, otherwise
-     * an IllegalArgumentException will be thrown.
-     * @param arguments a map or array of objects to be formatted
-     * @param result where text is appended
-     * @param pos On input: an alignment field, if desired
-     *            On output: the offsets of the alignment field
-     * @throws IllegalArgumentException if an argument in
-     *         <code>arguments</code> is not of the type
-     *         expected by the format element(s) that use it
-     * @throws IllegalArgumentException if <code>arguments<code> is
-     *         an array of Object and this format uses named arguments
-     * @stable ICU 3.0
-     */
-    public final StringBuffer format(Object arguments, StringBuffer result,
-                                     FieldPosition pos) {
-        FieldPosition jdkPos = toJDKFieldPosition(pos);
-        StringBuffer buf = messageFormat.format(arguments, result, jdkPos);
-        if (jdkPos != null) {
-            pos.setBeginIndex(jdkPos.getBeginIndex());
-            pos.setEndIndex(jdkPos.getEndIndex());
-        }
-        return buf;
-    }
-
-    /**
-     * Formats an array of objects and inserts them into the
-     * <code>MessageFormat</code>'s pattern, producing an
-     * <code>AttributedCharacterIterator</code>.
-     * You can use the returned <code>AttributedCharacterIterator</code>
-     * to build the resulting String, as well as to determine information
-     * about the resulting String.
-     * <p>
-     * The text of the returned <code>AttributedCharacterIterator</code> is
-     * the same that would be returned by
-     * <blockquote>
-     *     <code>{@link #format(java.lang.Object[], java.lang.StringBuffer,
-     *     java.text.FieldPosition) format}(arguments, new StringBuffer(), null).toString()</code>
-     * </blockquote>
-     * <p>
-     * In addition, the <code>AttributedCharacterIterator</code> contains at
-     * least attributes indicating where text was generated from an
-     * argument in the <code>arguments</code> array. The keys of these attributes are of
-     * type <code>MessageFormat.Field</code>, their values are
-     * <code>Integer</code> objects indicating the index in the <code>arguments</code>
-     * array of the argument from which the text was generated.
-     * <p>
-     * The attributes/value from the underlying <code>Format</code>
-     * instances that <code>MessageFormat</code> uses will also be
-     * placed in the resulting <code>AttributedCharacterIterator</code>.
-     * This allows you to not only find where an argument is placed in the
-     * resulting String, but also which fields it contains in turn.
-     *
-     * @param arguments an array of objects to be formatted and substituted.
-     * @return AttributedCharacterIterator describing the formatted value.
-     * @exception NullPointerException if <code>arguments</code> is null.
-     * @exception IllegalArgumentException if an argument in the
-     *            <code>arguments</code> array is not of the type
-     *            expected by the format element(s) that use it.
-     * @stable ICU 3.8
-     */
-    public AttributedCharacterIterator formatToCharacterIterator(Object arguments) {
-        AttributedCharacterIterator it = messageFormat.formatToCharacterIterator(arguments);
-
-        // Extract formatted String first
-        StringBuilder sb = new StringBuilder();
-        for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
-            sb.append(c);
-        }
-
-        // Create AttributedString
-        AttributedString attrstr = new AttributedString(sb.toString());
-
-        // Map JDK Field to ICU Field
-        int idx = 0;
-        it.first();
-        while (idx < it.getEndIndex()) {
-            int end = it.getRunLimit();
-            Map<Attribute, Object> attributes = it.getAttributes();
-            if (attributes != null) {
-                for (Entry<Attribute, Object> entry : attributes.entrySet()) {
-                    Attribute attr = entry.getKey();
-                    Object val = entry.getValue();
-                    if (attr.equals(java.text.MessageFormat.Field.ARGUMENT)) {
-                        val = attr = Field.ARGUMENT;
-                    }
-                    attrstr.addAttribute(attr, val, idx, end);
-                }
-            }
-            idx = end;
-            while (it.getIndex() < idx) {
-                it.next();
-            }
-        }
-
-        return attrstr.getIterator();
-    }
-
-    /**
-     * Parses the string.
-     *
-     * <p>Caveats: The parse may fail in a number of circumstances.
-     * For example:
-     * <ul>
-     * <li>If one of the arguments does not occur in the pattern.
-     * <li>If the format of an argument loses information, such as
-     *     with a choice format where a large number formats to "many".
-     * <li>Does not yet handle recursion (where
-     *     the substituted strings contain {n} references.)
-     * <li>Will not always find a match (or the correct match)
-     *     if some part of the parse is ambiguous.
-     *     For example, if the pattern "{1},{2}" is used with the
-     *     string arguments {"a,b", "c"}, it will format as "a,b,c".
-     *     When the result is parsed, it will return {"a", "b,c"}.
-     * <li>If a single argument is parsed more than once in the string,
-     *     then the later parse wins.
-     * </ul>
-     * When the parse fails, use ParsePosition.getErrorIndex() to find out
-     * where in the string did the parsing failed. The returned error
-     * index is the starting offset of the sub-patterns that the string
-     * is comparing with. For example, if the parsing string "AAA {0} BBB"
-     * is comparing against the pattern "AAD {0} BBB", the error index is
-     * 0. When an error occurs, the call to this method will return null.
-     * If the source is null, return an empty array.
-     * <p>
-     * This method is only supported with numbered arguments.  If
-     * the format pattern used named argument an
-     * IllegalArgumentException is thrown.
-     *
-     * @throws IllegalArgumentException if this format uses named arguments
-     * @stable ICU 3.0
-     */
-    public Object[] parse(String source, ParsePosition pos) {
-        return messageFormat.parse(source, pos);
-    }
-
-//    /**
-//     * {@icu} Parses the string, returning the results in a Map.
-//     * This is similar to the version that returns an array
-//     * of Object.  This supports both named and numbered
-//     * arguments-- if numbered, the keys in the map are the
-//     * corresponding Strings (e.g. "0", "1", "2"...).
-//     *
-//     * @param source the text to parse
-//     * @param pos the position at which to start parsing.  on return,
-//     *        contains the result of the parse.
-//     * @return a Map containing key/value pairs for each parsed argument.
-//     * @stable ICU 3.8
-//     */
-//    public Map<String, Object> parseToMap(String source, ParsePosition pos) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Parses text from the beginning of the given string to produce an object
-     * array.
-     * The method may not use the entire text of the given string.
-     * <p>
-     * See the {@link #parse(String, ParsePosition)} method for more information
-     * on message parsing.
-     *
-     * @param source A <code>String</code> whose beginning should be parsed.
-     * @return An <code>Object</code> array parsed from the string.
-     * @exception ParseException if the beginning of the specified string cannot be parsed.
-     * @exception IllegalArgumentException if this format uses named arguments
-     * @stable ICU 3.0
-     */
-    public Object[] parse(String source) throws ParseException {
-        return messageFormat.parse(source);
-    }
-
-//    /**
-//     * {@icu} Parses text from the beginning of the given string to produce a map from
-//     * argument to values. The method may not use the entire text of the given string.
-//     *
-//     * <p>See the {@link #parse(String, ParsePosition)} method for more information on
-//     * message parsing.
-//     *
-//     * @param source A <code>String</code> whose beginning should be parsed.
-//     * @return A <code>Map</code> parsed from the string.
-//     * @throws ParseException if the beginning of the specified string cannot
-//     *         be parsed.
-//     * @see #parseToMap(String, ParsePosition)
-//     * @stable ICU 3.8
-//     */
-//    public Map<String, Object> parseToMap(String source) throws ParseException {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Parses text from a string to produce an object array or Map.
-     * <p>
-     * The method attempts to parse text starting at the index given by
-     * <code>pos</code>.
-     * If parsing succeeds, then the index of <code>pos</code> is updated
-     * to the index after the last character used (parsing does not necessarily
-     * use all characters up to the end of the string), and the parsed
-     * object array is returned. The updated <code>pos</code> can be used to
-     * indicate the starting point for the next call to this method.
-     * If an error occurs, then the index of <code>pos</code> is not
-     * changed, the error index of <code>pos</code> is set to the index of
-     * the character where the error occurred, and null is returned.
-     * <p>
-     * See the {@link #parse(String, ParsePosition)} method for more information
-     * on message parsing.
-     *
-     * @param source A <code>String</code>, part of which should be parsed.
-     * @param pos A <code>ParsePosition</code> object with index and error
-     *            index information as described above.
-     * @return An <code>Object</code> parsed from the string, either an
-     *         array of Object, or a Map, depending on whether named
-     *         arguments are used.  This can be queried using <code>usesNamedArguments</code>.
-     *         In case of error, returns null.
-     * @throws NullPointerException if <code>pos</code> is null.
-     * @stable ICU 3.0
-     */
-    public Object parseObject(String source, ParsePosition pos) {
-        return messageFormat.parse(source, pos);
-    }
-
-    /**
-     * Overrides clone.
-     *
-     * @return a clone of this instance.
-     * @stable ICU 3.0
-     */
-    public Object clone() {
-        MessageFormat fmt = new MessageFormat((java.text.MessageFormat)messageFormat.clone());
-        fmt.savedPattern = savedPattern;
-        return fmt;
-    }
-
-    /**
-     * Overrides equals.
-     * @stable ICU 3.0
-     */
-    public boolean equals(Object obj) {
-        try {
-            return messageFormat.equals(((MessageFormat)obj).messageFormat);
-        }
-        catch (Exception e) {
-            return false;
-        }
-    }
-
-    /**
-     * Overrides hashCode.
-     * @stable ICU 3.0
-     */
-    public int hashCode() {
-        return messageFormat.hashCode();
-    }
-
-    /**
-     * Defines constants that are used as attribute keys in the
-     * <code>AttributedCharacterIterator</code> returned
-     * from <code>MessageFormat.formatToCharacterIterator</code>.
-     *
-     * @stable ICU 3.8
-     */
-    public static class Field extends Format.Field {
-
-        private static final long serialVersionUID = 7510380454602616157L;
-
-        /**
-         * Create a <code>Field</code> with the specified name.
-         *
-         * @param name The name of the attribute
-         *
-         * @stable ICU 3.8
-         */
-        protected Field(String name) {
-            super(name);
-        }
-
-        /**
-         * Resolves instances being deserialized to the predefined constants.
-         *
-         * @return resolved MessageFormat.Field constant
-         * @throws InvalidObjectException if the constant could not be resolved.
-         *
-         * @stable ICU 3.8
-         */
-        protected Object readResolve() throws InvalidObjectException {
-            if (this.getClass() != MessageFormat.Field.class) {
-                throw new InvalidObjectException(
-                    "A subclass of MessageFormat.Field must implement readResolve.");
-            }
-            if (this.getName().equals(ARGUMENT.getName())) {
-                return ARGUMENT;
-            } else {
-                throw new InvalidObjectException("Unknown attribute name.");
-            }
-        }
-
-        /**
-         * Constant identifying a portion of a message that was generated
-         * from an argument passed into <code>formatToCharacterIterator</code>.
-         * The value associated with the key will be an <code>Integer</code>
-         * indicating the index in the <code>arguments</code> array of the
-         * argument from which the text was generated.
-         *
-         * @stable ICU 3.8
-         */
-        public static final Field ARGUMENT = new Field("message argument field");
-
-    }
-
-    private static final char SINGLE_QUOTE = '\'';
-    private static final char CURLY_BRACE_LEFT = '{';
-    private static final char CURLY_BRACE_RIGHT = '}';
-
-    private static final int STATE_INITIAL = 0;
-    private static final int STATE_SINGLE_QUOTE = 1;
-    private static final int STATE_IN_QUOTE = 2;
-    private static final int STATE_MSG_ELEMENT = 3;
-
-    /**
-     * {@icu} Converts an 'apostrophe-friendly' pattern into a standard
-     * pattern.  Standard patterns treat all apostrophes as
-     * quotes, which is problematic in some languages, e.g.
-     * French, where apostrophe is commonly used.  This utility
-     * assumes that only an unpaired apostrophe immediately before
-     * a brace is a true quote.  Other unpaired apostrophes are paired,
-     * and the resulting standard pattern string is returned.
-     *
-     * <p><b>Note</b> it is not guaranteed that the returned pattern
-     * is indeed a valid pattern.  The only effect is to convert
-     * between patterns having different quoting semantics.
-     *
-     * @param pattern the 'apostrophe-friendly' patttern to convert
-     * @return the standard equivalent of the original pattern
-     * @stable ICU 3.4
-     */
-    public static String autoQuoteApostrophe(String pattern) {
-        StringBuilder buf = new StringBuilder(pattern.length() * 2);
-        int state = STATE_INITIAL;
-        int braceCount = 0;
-        for (int i = 0, j = pattern.length(); i < j; ++i) {
-            char c = pattern.charAt(i);
-            switch (state) {
-            case STATE_INITIAL:
-                switch (c) {
-                case SINGLE_QUOTE:
-                    state = STATE_SINGLE_QUOTE;
-                    break;
-                case CURLY_BRACE_LEFT:
-                    state = STATE_MSG_ELEMENT;
-                    ++braceCount;
-                    break;
-                }
-                break;
-            case STATE_SINGLE_QUOTE:
-                switch (c) {
-                case SINGLE_QUOTE:
-                    state = STATE_INITIAL;
-                    break;
-                case CURLY_BRACE_LEFT:
-                case CURLY_BRACE_RIGHT:
-                    state = STATE_IN_QUOTE;
-                    break;
-                default:
-                    buf.append(SINGLE_QUOTE);
-                    state = STATE_INITIAL;
-                    break;
-                }
-                break;
-            case STATE_IN_QUOTE:
-                switch (c) {
-                case SINGLE_QUOTE:
-                    state = STATE_INITIAL;
-                    break;
-                }
-                break;
-            case STATE_MSG_ELEMENT:
-                switch (c) {
-                case CURLY_BRACE_LEFT:
-                    ++braceCount;
-                    break;
-                case CURLY_BRACE_RIGHT:
-                    if (--braceCount == 0) {
-                        state = STATE_INITIAL;
-                    }
-                    break;
-                }
-                break;
-            ///CLOVER:OFF
-            default: // Never happens.
-                break;
-            ///CLOVER:ON
-            }
-            buf.append(c);
-        }
-        // End of scan
-        if (state == STATE_SINGLE_QUOTE || state == STATE_IN_QUOTE) {
-            buf.append(SINGLE_QUOTE);
-        }
-        return new String(buf);
-    }
-
-    private static FieldPosition toJDKFieldPosition(FieldPosition icuPos) {
-        if (icuPos == null) {
-            return null;
-        }
-
-        int fieldID = icuPos.getField();
-        Format.Field fieldAttribute = icuPos.getFieldAttribute();
-
-        FieldPosition jdkPos = null;
-        if (fieldAttribute != null) {
-            // map field
-            if (fieldAttribute.equals(Field.ARGUMENT)) {
-                fieldAttribute = java.text.MessageFormat.Field.ARGUMENT;
-            }
-            jdkPos = new FieldPosition(fieldAttribute, fieldID);
-        } else {
-            jdkPos = new FieldPosition(fieldID);
-        }
-
-        jdkPos.setBeginIndex(icuPos.getBeginIndex());
-        jdkPos.setEndIndex(icuPos.getEndIndex());
-
-        return jdkPos;
-
-    }
-
-    private void wrapNestedFormatters(java.text.MessageFormat mfmt) {
-        // Update nested formatters created by Java MessageFormat
-        // with ICU versions, so FieldPosition / AttributedText will
-        // use ICU formatter's definition, such as com.ibm.icu.text.NumberFormat.INTEGER_FIELD
-
-        // Replacing nested formatter may change the pattern string
-        // originally used. For example, "{0,integer} files" is replaced
-        // with "{0} files". We preserve the original pattern.
-        savedPattern = mfmt.toPattern();
-
-        Format[] subfmts = mfmt.getFormats();
-        for (int i = 0; i < subfmts.length; i++) {
-            if (subfmts[i] instanceof java.text.DateFormat) {
-                subfmts[i] = new DateFormat((java.text.DateFormat)subfmts[i]);
-            } else if (subfmts[i] instanceof java.text.NumberFormat) {
-                subfmts[i] = new NumberFormat((java.text.NumberFormat)subfmts[i]);
-            }
-        }
-        mfmt.setFormats(subfmts);
-    }
-
-    private String savedPattern;
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/NumberFormat.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/NumberFormat.java
deleted file mode 100644
index 88c3f54..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/NumberFormat.java
+++ /dev/null
@@ -1,1316 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 1996-2012, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.text;
-
-import java.io.InvalidObjectException;
-import java.math.BigInteger;
-import java.text.FieldPosition;
-import java.text.Format;
-import java.text.ParseException;
-import java.text.ParsePosition;
-import java.util.Locale;
-import java.util.Set;
-
-import com.ibm.icu.util.Currency;
-import com.ibm.icu.util.ULocale;
-import com.ibm.icu.util.ULocale.Category;
-
-/**
- * {@icuenhanced java.text.NumberFormat}.{@icu _usage_}
- *
- * <code>NumberFormat</code> is the abstract base class for all number
- * formats. This class provides the interface for formatting and parsing
- * numbers. <code>NumberFormat</code> also provides methods for determining
- * which locales have number formats, and what their names are.
- *
- * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
- * Your code can be completely independent of the locale conventions for
- * decimal points, thousands-separators, or even the particular decimal
- * digits used, or whether the number format is even decimal.
- *
- * <p>
- * To format a number for the current Locale, use one of the factory
- * class methods:
- * <blockquote>
- * <pre>
- *  myString = NumberFormat.getInstance().format(myNumber);
- * </pre>
- * </blockquote>
- * If you are formatting multiple numbers, it is
- * more efficient to get the format and use it multiple times so that
- * the system doesn't have to fetch the information about the local
- * language and country conventions multiple times.
- * <blockquote>
- * <pre>
- * NumberFormat nf = NumberFormat.getInstance();
- * for (int i = 0; i < a.length; ++i) {
- *     output.println(nf.format(myNumber[i]) + "; ");
- * }
- * </pre>
- * </blockquote>
- * To format a number for a different Locale, specify it in the
- * call to <code>getInstance</code>.
- * <blockquote>
- * <pre>
- * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
- * </pre>
- * </blockquote>
- * You can also use a <code>NumberFormat</code> to parse numbers:
- * <blockquote>
- * <pre>
- * myNumber = nf.parse(myString);
- * </pre>
- * </blockquote>
- * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the
- * normal number format. Use <code>getIntegerInstance</code> to get an
- * integer number format. Use <code>getCurrencyInstance</code> to get the
- * currency number format. And use <code>getPercentInstance</code> to get a
- * format for displaying percentages. With this format, a fraction like
- * 0.53 is displayed as 53%.
- *
- * <p>
- * Starting from ICU 4.2, you can use getInstance() by passing in a 'style'
- * as parameter to get the correct instance.
- * For example,
- * use getInstance(...NUMBERSTYLE) to get the normal number format,
- * getInstance(...PERCENTSTYLE) to get a format for displaying percentage,
- * getInstance(...SCIENTIFICSTYLE) to get a format for displaying scientific number,
- * getInstance(...INTEGERSTYLE) to get an integer number format,
- * getInstance(...CURRENCYSTYLE) to get the currency number format,
- * in which the currency is represented by its symbol, for example, "$3.00".
- * getInstance(...ISOCURRENCYSTYLE)  to get the currency number format,
- * in which the currency is represented by its ISO code, for example "USD3.00".
- * getInstance(...PLURALCURRENCYSTYLE) to get the currency number format,
- * in which the currency is represented by its full name in plural format,
- * for example, "3.00 US dollars" or "1.00 US dollar".
- *
- *
- * <p>
- * You can also control the display of numbers with such methods as
- * <code>setMinimumFractionDigits</code>.
- * If you want even more control over the format or parsing,
- * or want to give your users more control,
- * you can try casting the <code>NumberFormat</code> you get from the factory methods
- * to a <code>DecimalFormat</code>. This will work for the vast majority
- * of locales; just remember to put it in a <code>try</code> block in case you
- * encounter an unusual one.
- *
- * <p>
- * NumberFormat is designed such that some controls
- * work for formatting and others work for parsing.  The following is
- * the detailed description for each these control methods,
- * <p>
- * setParseIntegerOnly : only affects parsing, e.g.
- * if true,  "3456.78" -> 3456 (and leaves the parse position just after '6')
- * if false, "3456.78" -> 3456.78 (and leaves the parse position just after '8')
- * This is independent of formatting.  If you want to not show a decimal point
- * where there might be no digits after the decimal point, use
- * setDecimalSeparatorAlwaysShown on DecimalFormat.
- * <p>
- * You can also use forms of the <code>parse</code> and <code>format</code>
- * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to
- * allow you to:
- * <ul>
- * <li> progressively parse through pieces of a string
- * <li> align the decimal point and other areas
- * </ul>
- * For example, you can align numbers in two ways:
- * <ol>
- * <li> If you are using a monospaced font with spacing for alignment,
- *      you can pass the <code>FieldPosition</code> in your format call, with
- *      <code>field</code> = <code>INTEGER_FIELD</code>. On output,
- *      <code>getEndIndex</code> will be set to the offset between the
- *      last character of the integer and the decimal. Add
- *      (desiredSpaceCount - getEndIndex) spaces at the front of the string.
- *
- * <li> If you are using proportional fonts,
- *      instead of padding with spaces, measure the width
- *      of the string in pixels from the start to <code>getEndIndex</code>.
- *      Then move the pen by
- *      (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.
- *      It also works where there is no decimal, but possibly additional
- *      characters at the end, e.g., with parentheses in negative
- *      numbers: "(12)" for -12.
- * </ol>
- *
- * <h4>Synchronization</h4>
- * <p>
- * Number formats are generally not synchronized. It is recommended to create
- * separate format instances for each thread. If multiple threads access a format
- * concurrently, it must be synchronized externally.
- * <p>
- *
- * <h4>DecimalFormat</h4>
- * <p>DecimalFormat is the concrete implementation of NumberFormat, and the
- * NumberFormat API is essentially an abstraction from DecimalFormat's API.
- * Refer to DecimalFormat for more information about this API.</p>
- *
- * see          DecimalFormat
- * see          java.text.ChoiceFormat
- * @author       Mark Davis
- * @author       Helena Shih
- * @author       Alan Liu
- * @stable ICU 2.0
- */
-public class NumberFormat extends Format {
-    private static final long serialVersionUID = 1;
-
-    /**
-     * @internal
-     */
-    public final java.text.NumberFormat numberFormat;
-        
-    /**
-     * @internal
-     * @param delegate the NumberFormat to which to delegate
-     */
-    public NumberFormat(java.text.NumberFormat delegate) {
-        this.numberFormat = delegate;
-    }
-
-    /**
-     * {@icu} Constant to specify normal number style of format.
-     * @stable ICU 4.2
-     */
-    public static final int NUMBERSTYLE = 0;
-    /**
-     * {@icu} Constant to specify currency style of format which uses currency symbol
-     * to represent currency, for example: "$3.00".
-     * @stable ICU 4.2
-     */
-    public static final int CURRENCYSTYLE = 1;
-    /**
-     * {@icu} Constant to specify a style of format to display percent.
-     * @stable ICU 4.2
-     */
-    public static final int PERCENTSTYLE = 2;
-    /**
-     * {@icu} Constant to specify a style of format to display scientific number.
-     * @stable ICU 4.2
-     */
-    public static final int SCIENTIFICSTYLE = 3;
-    /**
-     * {@icu} Constant to specify a integer number style format.
-     * @stable ICU 4.2
-     */
-    public static final int INTEGERSTYLE = 4;
-    /**
-     * {@icu} Constant to specify currency style of format which uses currency
-     * ISO code to represent currency, for example: "USD3.00".
-     * @stable ICU 4.2
-     */
-    public static final int ISOCURRENCYSTYLE = 5;
-    /**
-     * {@icu} Constant to specify currency style of format which uses currency
-     * long name with plural format to represent currency, for example,
-     * "3.00 US Dollars".
-     * @stable ICU 4.2
-     */
-    public static final int PLURALCURRENCYSTYLE = 6;
-
-    /**
-     * Field constant used to construct a FieldPosition object. Signifies that
-     * the position of the integer part of a formatted number should be returned.
-     * @see java.text.FieldPosition
-     * @stable ICU 2.0
-     */
-    public static final int INTEGER_FIELD = 0;
-
-    /**
-     * Field constant used to construct a FieldPosition object. Signifies that
-     * the position of the fraction part of a formatted number should be returned.
-     * @see java.text.FieldPosition
-     * @stable ICU 2.0
-     */
-    public static final int FRACTION_FIELD = 1;
-
-    /**
-     * Formats a number and appends the resulting text to the given string buffer.
-     * {@icunote} recognizes <code>BigInteger</code>
-     * and <code>BigDecimal</code> objects.
-     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
-     * @stable ICU 2.0
-     */
-    public StringBuffer format(Object number,
-                               StringBuffer toAppendTo,
-                               FieldPosition pos) {
-        FieldPosition jdkPos = toJDKFieldPosition(pos);
-        StringBuffer buf = numberFormat.format(number, toAppendTo, jdkPos);
-        if (jdkPos != null) {
-            pos.setBeginIndex(jdkPos.getBeginIndex());
-            pos.setEndIndex(jdkPos.getEndIndex());
-        }
-        return buf;
-    }
-
-    /**
-     * Parses text from a string to produce a number.
-     * @param source the String to parse
-     * @param parsePosition the position at which to start the parse
-     * @return the parsed number, or null
-     * @see java.text.NumberFormat#parseObject(String, ParsePosition)
-     * @stable ICU 2.0
-     */
-    public final Object parseObject(String source,
-                                    ParsePosition parsePosition) {
-        return numberFormat.parse(source, parsePosition);
-    }
-
-    /**
-     * Specialization of format.
-     * @see java.text.Format#format(Object)
-     * @stable ICU 2.0
-     */
-    public final String format(double number) {
-        return numberFormat.format(number);
-    }
-
-    /**
-     * Specialization of format.
-     * @see java.text.Format#format(Object)
-     * @stable ICU 2.0
-     */
-    public final String format(long number) {
-        return numberFormat.format(number);
-    }
-
-    /**
-     * {@icu} Convenience method to format a BigInteger.
-     * @stable ICU 2.0
-     */
-    public final String format(BigInteger number) {
-        return numberFormat.format(number);
-    }
-
-    /**
-     * Convenience method to format a BigDecimal.
-     * @stable ICU 2.0
-     */
-    public final String format(java.math.BigDecimal number) {
-        return numberFormat.format(number);
-    }
-
-    /**
-     * {@icu} Convenience method to format an ICU BigDecimal.
-     * @stable ICU 2.0
-     */
-    public final String format(com.ibm.icu.math.BigDecimal number) {
-        return numberFormat.format(number.toBigDecimal());
-    }
-
-//    /**
-//     * {@icu} Convenience method to format a CurrencyAmount.
-//     * @stable ICU 3.0
-//     */
-//    public final String format(CurrencyAmount currAmt) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Specialization of format.
-     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
-     * @stable ICU 2.0
-     */
-    public StringBuffer format(double number,
-                                        StringBuffer toAppendTo,
-                                        FieldPosition pos) {
-        FieldPosition jdkPos = toJDKFieldPosition(pos);
-        StringBuffer buf = numberFormat.format(number, toAppendTo, jdkPos);
-        pos.setBeginIndex(jdkPos.getBeginIndex());
-        pos.setEndIndex(jdkPos.getEndIndex());
-        return buf;
-    }
-
-    /**
-     * Specialization of format.
-     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
-     * @stable ICU 2.0
-     */
-    public StringBuffer format(long number,
-                                        StringBuffer toAppendTo,
-                                        FieldPosition pos) {
-        FieldPosition jdkPos = toJDKFieldPosition(pos);
-        StringBuffer buf = numberFormat.format(number, toAppendTo, jdkPos);
-        pos.setBeginIndex(jdkPos.getBeginIndex());
-        pos.setEndIndex(jdkPos.getEndIndex());
-        return buf;
-    }
-    /**
-     * {@icu} Formats a BigInteger. Specialization of format.
-     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
-     * @stable ICU 2.0
-     */
-    public StringBuffer format(BigInteger number,
-                                        StringBuffer toAppendTo,
-                                        FieldPosition pos) {
-        FieldPosition jdkPos = toJDKFieldPosition(pos);
-        StringBuffer buf = numberFormat.format(number, toAppendTo, jdkPos);
-        pos.setBeginIndex(jdkPos.getBeginIndex());
-        pos.setEndIndex(jdkPos.getEndIndex());
-        return buf;
-    }
-    /**
-     * {@icu} Formats a BigDecimal. Specialization of format.
-     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
-     * @stable ICU 2.0
-     */
-    public StringBuffer format(java.math.BigDecimal number,
-                                        StringBuffer toAppendTo,
-                                        FieldPosition pos) {
-        FieldPosition jdkPos = toJDKFieldPosition(pos);
-        StringBuffer buf = numberFormat.format(number, toAppendTo, jdkPos);
-        pos.setBeginIndex(jdkPos.getBeginIndex());
-        pos.setEndIndex(jdkPos.getEndIndex());
-        return buf;
-    }
-    /**
-     * {@icu} Formats an ICU BigDecimal. Specialization of format.
-     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
-     * @stable ICU 2.0
-     */
-    public StringBuffer format(com.ibm.icu.math.BigDecimal number,
-                                        StringBuffer toAppendTo,
-                                        FieldPosition pos) {
-        FieldPosition jdkPos = toJDKFieldPosition(pos);
-        StringBuffer buf = numberFormat.format(number.toBigDecimal(), toAppendTo, jdkPos);
-        pos.setBeginIndex(jdkPos.getBeginIndex());
-        pos.setEndIndex(jdkPos.getEndIndex());
-        return buf;
-    }
-
-//    /**
-//     * {@icu} Formats a CurrencyAmount. Specialization of format.
-//     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
-//     * @stable ICU 3.0
-//     */
-//    public StringBuffer format(CurrencyAmount currAmt,
-//                               StringBuffer toAppendTo,
-//                               FieldPosition pos) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
-     * Long.MAX_VALUE] and with no decimals), otherwise a Double.
-     * If IntegerOnly is set, will stop at a decimal
-     * point (or equivalent; e.g., for rational numbers "1 2/3", will stop
-     * after the 1).
-     * Does not throw an exception; if no object can be parsed, index is
-     * unchanged!
-     * @see #isParseIntegerOnly
-     * @see java.text.Format#parseObject(String, ParsePosition)
-     * @stable ICU 2.0
-     */
-    public Number parse(String text, ParsePosition parsePosition) {
-        return numberFormat.parse(text, parsePosition);
-    }
-
-    /**
-     * Parses text from the beginning of the given string to produce a number.
-     * The method might not use the entire text of the given string.
-     *
-     * @param text A String whose beginning should be parsed.
-     * @return A Number parsed from the string.
-     * @throws ParseException if the beginning of the specified string
-     * cannot be parsed.
-     * @see #format
-     * @stable ICU 2.0
-     */
-    public Number parse(String text) throws ParseException {
-        return numberFormat.parse(text);
-    }
-
-//    /**
-//     * Parses text from the given string as a CurrencyAmount.  Unlike
-//     * the parse() method, this method will attempt to parse a generic
-//     * currency name, searching for a match of this object's locale's
-//     * currency display names, or for a 3-letter ISO currency code.
-//     * This method will fail if this format is not a currency format,
-//     * that is, if it does not contain the currency pattern symbol
-//     * (U+00A4) in its prefix or suffix.
-//     *
-//     * @param text the text to parse
-//     * @param pos input-output position; on input, the position within
-//     * text to match; must have 0 <= pos.getIndex() < text.length();
-//     * on output, the position after the last matched character. If
-//     * the parse fails, the position in unchanged upon output.
-//     * @return a CurrencyAmount, or null upon failure
-//     * @draft ICU 49
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public CurrencyAmount parseCurrency(CharSequence text, ParsePosition pos) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Returns true if this format will parse numbers as integers only.
-     * For example in the English locale, with ParseIntegerOnly true, the
-     * string "1234." would be parsed as the integer value 1234 and parsing
-     * would stop at the "." character.  The decimal separator accepted
-     * by the parse operation is locale-dependent and determined by the
-     * subclass.
-     * @return true if this will parse integers only
-     * @stable ICU 2.0
-     */
-    public boolean isParseIntegerOnly() {
-        return numberFormat.isParseIntegerOnly();
-    }
-
-    /**
-     * Sets whether or not numbers should be parsed as integers only.
-     * @param value true if this should parse integers only
-     * @see #isParseIntegerOnly
-     * @stable ICU 2.0
-     */
-    public void setParseIntegerOnly(boolean value) {
-        numberFormat.setParseIntegerOnly(value);
-    }
-
-//    /**
-//     * {@icu} Sets whether strict parsing is in effect.  When this is true, the
-//     * following conditions cause a parse failure (examples use the pattern "#,##0.#"):<ul>
-//     * <li>Leading zeros<br>
-//     * '00', '0123' fail the parse, but '0' and '0.001' pass</li>
-//     * <li>Leading or doubled grouping separators<br>
-//     * ',123' and '1,,234" fail</li>
-//     * <li>Groups of incorrect length when grouping is used<br>
-//     * '1,23' and '1234,567' fail, but '1234' passes</li>
-//     * <li>Grouping separators used in numbers followed by exponents<br>
-//     * '1,234E5' fails, but '1234E5' and '1,234E' pass ('E' is not an exponent when
-//     * not followed by a number)</li>
-//     * </ul>
-//     * When strict parsing is off, leading zeros and all grouping separators are ignored.
-//     * This is the default behavior.
-//     * @param value True to enable strict parsing.  Default is false.
-//     * @see #isParseStrict
-//     * @stable ICU 3.6
-//     */
-//    public void setParseStrict(boolean value) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns whether strict parsing is in effect.
-//     * @return true if strict parsing is in effect
-//     * @see #setParseStrict
-//     * @stable ICU 3.6
-//     */
-//    public boolean isParseStrict() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    //============== Locale Stuff =====================
-
-    /**
-     * Returns the default number format for the current default locale.
-     * The default format is one of the styles provided by the other
-     * factory methods: getNumberInstance, getIntegerInstance,
-     * getCurrencyInstance or getPercentInstance.
-     * Exactly which one is locale-dependent.
-     * @stable ICU 2.0
-     */
-    //Bug 4408066 [Richard/GCL]
-    public final static NumberFormat getInstance() {
-        return getInstance(ULocale.getDefault(Category.FORMAT), NUMBERSTYLE);
-    }
-
-    /**
-     * Returns the default number format for the specified locale.
-     * The default format is one of the styles provided by the other
-     * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
-     * Exactly which one is locale-dependent.
-     * @stable ICU 2.0
-     */
-    public static NumberFormat getInstance(Locale inLocale) {
-        return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);
-    }
-
-    /**
-     * {@icu} Returns the default number format for the specified locale.
-     * The default format is one of the styles provided by the other
-     * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
-     * Exactly which one is locale-dependent.
-     * @stable ICU 3.2
-     */
-    public static NumberFormat getInstance(ULocale inLocale) {
-        return getInstance(inLocale, NUMBERSTYLE);
-    }
-
-    /**
-     * {@icu} Returns a specific style number format for default locale.
-     * @param style  number format style
-     * @stable ICU 4.2
-     */
-    public final static NumberFormat getInstance(int style) {
-        return getInstance(ULocale.getDefault(Category.FORMAT), style);
-    }
-
-    /**
-     * {@icu} Returns a specific style number format for a specific locale.
-     * @param inLocale  the specific locale.
-     * @param style     number format style
-     * @stable ICU 4.2
-     */
-    public static NumberFormat getInstance(Locale inLocale, int style) {
-        return getInstance(ULocale.forLocale(inLocale), style);
-    }
-
-
-    /**
-     * Returns a general-purpose number format for the current default locale.
-     * @stable ICU 2.0
-     */
-    public final static NumberFormat getNumberInstance() {
-        return getInstance(ULocale.getDefault(Category.FORMAT), NUMBERSTYLE);
-    }
-
-    /**
-     * Returns a general-purpose number format for the specified locale.
-     * @stable ICU 2.0
-     */
-    public static NumberFormat getNumberInstance(Locale inLocale) {
-        return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);
-    }
-
-    /**
-     * {@icu} Returns a general-purpose number format for the specified locale.
-     * @stable ICU 3.2
-     */
-    public static NumberFormat getNumberInstance(ULocale inLocale) {
-        return getInstance(inLocale, NUMBERSTYLE);
-    }
-
-    /**
-     * Returns an integer number format for the current default locale. The
-     * returned number format is configured to round floating point numbers
-     * to the nearest integer using IEEE half-even rounding (see {@link
-     * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
-     * and to parse only the integer part of an input string (see {@link
-     * #isParseIntegerOnly isParseIntegerOnly}).
-     *
-     * @return a number format for integer values
-     * @stable ICU 2.0
-     */
-    //Bug 4408066 [Richard/GCL]
-    public final static NumberFormat getIntegerInstance() {
-        return getInstance(ULocale.getDefault(Category.FORMAT), INTEGERSTYLE);
-    }
-
-    /**
-     * Returns an integer number format for the specified locale. The
-     * returned number format is configured to round floating point numbers
-     * to the nearest integer using IEEE half-even rounding (see {@link
-     * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
-     * and to parse only the integer part of an input string (see {@link
-     * #isParseIntegerOnly isParseIntegerOnly}).
-     *
-     * @param inLocale the locale for which a number format is needed
-     * @return a number format for integer values
-     * @stable ICU 2.0
-     */
-    //Bug 4408066 [Richard/GCL]
-    public static NumberFormat getIntegerInstance(Locale inLocale) {
-        return getInstance(ULocale.forLocale(inLocale), INTEGERSTYLE);
-    }
-
-    /**
-     * {@icu} Returns an integer number format for the specified locale. The
-     * returned number format is configured to round floating point numbers
-     * to the nearest integer using IEEE half-even rounding (see {@link
-     * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
-     * and to parse only the integer part of an input string (see {@link
-     * #isParseIntegerOnly isParseIntegerOnly}).
-     *
-     * @param inLocale the locale for which a number format is needed
-     * @return a number format for integer values
-     * @stable ICU 3.2
-     */
-    public static NumberFormat getIntegerInstance(ULocale inLocale) {
-        return getInstance(inLocale, INTEGERSTYLE);
-    }
-
-    /**
-     * Returns a currency format for the current default locale.
-     * @return a number format for currency
-     * @stable ICU 2.0
-     */
-    public final static NumberFormat getCurrencyInstance() {
-        return getInstance(ULocale.getDefault(Category.FORMAT), CURRENCYSTYLE);
-    }
-
-    /**
-     * Returns a currency format for the specified locale.
-     * @return a number format for currency
-     * @stable ICU 2.0
-     */
-    public static NumberFormat getCurrencyInstance(Locale inLocale) {
-        return getInstance(ULocale.forLocale(inLocale), CURRENCYSTYLE);
-    }
-
-    /**
-     * {@icu} Returns a currency format for the specified locale.
-     * @return a number format for currency
-     * @stable ICU 3.2
-     */
-    public static NumberFormat getCurrencyInstance(ULocale inLocale) {
-        return getInstance(inLocale, CURRENCYSTYLE);
-    }
-
-    /**
-     * Returns a percentage format for the current default locale.
-     * @return a number format for percents
-     * @stable ICU 2.0
-     */
-    public final static NumberFormat getPercentInstance() {
-        return getInstance(ULocale.getDefault(Category.FORMAT), PERCENTSTYLE);
-    }
-
-    /**
-     * Returns a percentage format for the specified locale.
-     * @return a number format for percents
-     * @stable ICU 2.0
-     */
-    public static NumberFormat getPercentInstance(Locale inLocale) {
-        return getInstance(ULocale.forLocale(inLocale), PERCENTSTYLE);
-    }
-
-    /**
-     * {@icu} Returns a percentage format for the specified locale.
-     * @return a number format for percents
-     * @stable ICU 3.2
-     */
-    public static NumberFormat getPercentInstance(ULocale inLocale) {
-        return getInstance(inLocale, PERCENTSTYLE);
-    }
-
-    /**
-     * {@icu} Returns a scientific format for the current default locale.
-     * @return a scientific number format
-     * @stable ICU 2.0
-     */
-    public final static NumberFormat getScientificInstance() {
-        return getInstance(ULocale.getDefault(Category.FORMAT), SCIENTIFICSTYLE);
-    }
-
-    /**
-     * {@icu} Returns a scientific format for the specified locale.
-     * @return a scientific number format
-     * @stable ICU 2.0
-     */
-    public static NumberFormat getScientificInstance(Locale inLocale) {
-        return getInstance(ULocale.forLocale(inLocale), SCIENTIFICSTYLE);
-    }
-
-    /**
-     * {@icu} Returns a scientific format for the specified locale.
-     * @return a scientific number format
-     * @stable ICU 3.2
-     */
-    public static NumberFormat getScientificInstance(ULocale inLocale) {
-        return getInstance(inLocale, SCIENTIFICSTYLE);
-    }
-
-    /**
-     * A NumberFormatFactory is used to register new number formats.  The factory
-     * should be able to create any of the predefined formats for each locale it
-     * supports.  When registered, the locales it supports extend or override the
-     * locales already supported by ICU.
-     *
-     * <p><b>Note:</b> as of ICU4J 3.2, the default API for NumberFormatFactory uses
-     * ULocale instead of Locale.  Instead of overriding createFormat(Locale, int),
-     * new implementations should override createFactory(ULocale, int).  Note that
-     * one of these two methods <b>MUST</b> be overridden or else an infinite
-     * loop will occur.
-     *
-     * @stable ICU 2.6
-     */
-    public static abstract class NumberFormatFactory {
-        /**
-         * Value passed to format requesting a default number format.
-         * @stable ICU 2.6
-         */
-        public static final int FORMAT_NUMBER = NUMBERSTYLE;
-
-        /**
-         * Value passed to format requesting a currency format.
-         * @stable ICU 2.6
-         */
-        public static final int FORMAT_CURRENCY = CURRENCYSTYLE;
-
-        /**
-         * Value passed to format requesting a percent format.
-         * @stable ICU 2.6
-         */
-        public static final int FORMAT_PERCENT = PERCENTSTYLE;
-
-        /**
-         * Value passed to format requesting a scientific format.
-         * @stable ICU 2.6
-         */
-        public static final int FORMAT_SCIENTIFIC = SCIENTIFICSTYLE;
-
-        /**
-         * Value passed to format requesting an integer format.
-         * @stable ICU 2.6
-         */
-        public static final int FORMAT_INTEGER = INTEGERSTYLE;
-
-        /**
-         * Returns true if this factory is visible.  Default is true.
-         * If not visible, the locales supported by this factory will not
-         * be listed by getAvailableLocales.  This value must not change.
-         * @return true if the factory is visible.
-         * @stable ICU 2.6
-         */
-        public boolean visible() {
-            return true;
-        }
-
-        /**
-         * Returns an immutable collection of the locale names directly
-         * supported by this factory.
-         * @return the supported locale names.
-         * @stable ICU 2.6
-         */
-         public abstract Set<String> getSupportedLocaleNames();
-
-        /**
-         * Returns a number format of the appropriate type.  If the locale
-         * is not supported, return null.  If the locale is supported, but
-         * the type is not provided by this service, return null.  Otherwise
-         * return an appropriate instance of NumberFormat.
-         * <b>Note:</b> as of ICU4J 3.2, implementations should override
-         * this method instead of createFormat(Locale, int).
-         * @param loc the locale for which to create the format
-         * @param formatType the type of format
-         * @return the NumberFormat, or null.
-         * @stable ICU 3.2
-         */
-        public NumberFormat createFormat(ULocale loc, int formatType) {
-            return createFormat(loc.toLocale(), formatType);
-        }
-
-        /**
-         * Returns a number format of the appropriate type.  If the locale
-         * is not supported, return null.  If the locale is supported, but
-         * the type is not provided by this service, return null.  Otherwise
-         * return an appropriate instance of NumberFormat.
-         * <b>Note:</b> as of ICU4J 3.2, createFormat(ULocale, int) should be
-         * overridden instead of this method.  This method is no longer
-         * abstract and delegates to that method.
-         * @param loc the locale for which to create the format
-         * @param formatType the type of format
-         * @return the NumberFormat, or null.
-         * @stable ICU 2.6
-         */
-        public NumberFormat createFormat(Locale loc, int formatType) {
-            return createFormat(ULocale.forLocale(loc), formatType);
-        }
-
-        /**
-         * @stable ICU 2.6
-         */
-        protected NumberFormatFactory() {
-        }
-    }
-
-    /**
-     * Returns the list of Locales for which NumberFormats are available.
-     * @return the available locales
-     * @stable ICU 2.0
-     */
-    public static Locale[] getAvailableLocales() {
-        return java.text.NumberFormat.getAvailableLocales();
-    }
-
-    /**
-     * {@icu} Returns the list of Locales for which NumberFormats are available.
-     * @return the available locales
-     * @draft ICU 3.2 (retain)
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static ULocale[] getAvailableULocales() {
-        if (availableULocales == null) {
-            synchronized (NumberFormat.class) {
-                if (availableULocales == null) {
-                    Locale[] locales = java.text.NumberFormat.getAvailableLocales();
-                    ULocale[] ulocales = new ULocale[locales.length];
-                    for (int i = 0; i < locales.length; ++i) {
-                        ulocales[i] = ULocale.forLocale(locales[i]);
-                    }
-                    availableULocales = ulocales;
-                }
-            }
-        }
-        return (ULocale[])availableULocales.clone();
-    }
-    private static volatile ULocale[] availableULocales;
-
-//    /**
-//     * {@icu} Registers a new NumberFormatFactory.  The factory is adopted by
-//     * the service and must not be modified.  The returned object is a
-//     * key that can be used to unregister this factory.
-//     * @param factory the factory to register
-//     * @return a key with which to unregister the factory
-//     * @stable ICU 2.6
-//     */
-//    public static Object registerFactory(NumberFormatFactory factory) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Unregisters the factory or instance associated with this key (obtained from
-//     * registerInstance or registerFactory).
-//     * @param registryKey a key obtained from registerFactory
-//     * @return true if the object was successfully unregistered
-//     * @stable ICU 2.6
-//     */
-//    public static boolean unregister(Object registryKey) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Overrides hashCode.
-     * @stable ICU 2.0
-     */
-    public int hashCode() {
-        return numberFormat.hashCode();
-    }
-
-    /**
-     * Overrides equals.
-     * Two NumberFormats are equal if they are of the same class
-     * and the settings (groupingUsed, parseIntegerOnly, maximumIntegerDigits, etc.
-     * are equal.
-     * @param obj the object to compare against
-     * @return true if the object is equal to this.
-     * @stable ICU 2.0
-     */
-    public boolean equals(Object obj) {
-        try {
-            return numberFormat.equals(((NumberFormat)obj).numberFormat);
-        }
-        catch (Exception e) {
-            return false;
-        }
-    }
-
-    /**
-     * Overrides clone.
-     * @stable ICU 2.0
-     */
-    public Object clone() {
-        return new NumberFormat((java.text.NumberFormat)numberFormat.clone());
-    }
-
-    /**
-     * Returns true if grouping is used in this format. For example, in the
-     * en_US locale, with grouping on, the number 1234567 will be formatted
-     * as "1,234,567". The grouping separator as well as the size of each group
-     * is locale-dependent and is determined by subclasses of NumberFormat.
-     * Grouping affects both parsing and formatting.
-     * @return true if grouping is used
-     * @see #setGroupingUsed
-     * @stable ICU 2.0
-     */
-    public boolean isGroupingUsed() {
-        return numberFormat.isGroupingUsed();
-    }
-
-    /**
-     * Sets whether or not grouping will be used in this format.  Grouping
-     * affects both parsing and formatting.
-     * @see #isGroupingUsed
-     * @param newValue true to use grouping.
-     * @stable ICU 2.0
-     */
-    public void setGroupingUsed(boolean newValue) {
-        numberFormat.setGroupingUsed(newValue);
-    }
-
-    /**
-     * Returns the maximum number of digits allowed in the integer portion of a
-     * number.  The default value is 40, which subclasses can override.
-     * When formatting, the exact behavior when this value is exceeded is
-     * subclass-specific.  When parsing, this has no effect.
-     * @return the maximum number of integer digits
-     * @see #setMaximumIntegerDigits
-     * @stable ICU 2.0
-     */
-    public int getMaximumIntegerDigits() {
-        return numberFormat.getMaximumIntegerDigits();
-    }
-
-    /**
-     * Sets the maximum number of digits allowed in the integer portion of a
-     * number. This must be >= minimumIntegerDigits.  If the
-     * new value for maximumIntegerDigits is less than the current value
-     * of minimumIntegerDigits, then minimumIntegerDigits will also be set to
-     * the new value.
-     * @param newValue the maximum number of integer digits to be shown; if
-     * less than zero, then zero is used.  Subclasses might enforce an
-     * upper limit to this value appropriate to the numeric type being formatted.
-     * @see #getMaximumIntegerDigits
-     * @stable ICU 2.0
-     */
-    public void setMaximumIntegerDigits(int newValue) {
-        numberFormat.setMaximumIntegerDigits(newValue);
-    }
-
-    /**
-     * Returns the minimum number of digits allowed in the integer portion of a
-     * number.  The default value is 1, which subclasses can override.
-     * When formatting, if this value is not reached, numbers are padded on the
-     * left with the locale-specific '0' character to ensure at least this
-     * number of integer digits.  When parsing, this has no effect.
-     * @return the minimum number of integer digits
-     * @see #setMinimumIntegerDigits
-     * @stable ICU 2.0
-     */
-    public int getMinimumIntegerDigits() {
-        return numberFormat.getMinimumIntegerDigits();
-    }
-
-    /**
-     * Sets the minimum number of digits allowed in the integer portion of a
-     * number.  This must be <= maximumIntegerDigits.  If the
-     * new value for minimumIntegerDigits is more than the current value
-     * of maximumIntegerDigits, then maximumIntegerDigits will also be set to
-     * the new value.
-     * @param newValue the minimum number of integer digits to be shown; if
-     * less than zero, then zero is used. Subclasses might enforce an
-     * upper limit to this value appropriate to the numeric type being formatted.
-     * @see #getMinimumIntegerDigits
-     * @stable ICU 2.0
-     */
-    public void setMinimumIntegerDigits(int newValue) {
-        numberFormat.setMinimumIntegerDigits(newValue);
-    }
-
-    /**
-     * Returns the maximum number of digits allowed in the fraction
-     * portion of a number.  The default value is 3, which subclasses
-     * can override.  When formatting, the exact behavior when this
-     * value is exceeded is subclass-specific.  When parsing, this has
-     * no effect.
-     * @return the maximum number of fraction digits
-     * @see #setMaximumFractionDigits
-     * @stable ICU 2.0
-     */
-    public int getMaximumFractionDigits() {
-        return numberFormat.getMaximumFractionDigits();
-    }
-
-    /**
-     * Sets the maximum number of digits allowed in the fraction portion of a
-     * number. This must be >= minimumFractionDigits.  If the
-     * new value for maximumFractionDigits is less than the current value
-     * of minimumFractionDigits, then minimumFractionDigits will also be set to
-     * the new value.
-     * @param newValue the maximum number of fraction digits to be shown; if
-     * less than zero, then zero is used. The concrete subclass may enforce an
-     * upper limit to this value appropriate to the numeric type being formatted.
-     * @see #getMaximumFractionDigits
-     * @stable ICU 2.0
-     */
-    public void setMaximumFractionDigits(int newValue) {
-        numberFormat.setMaximumFractionDigits(newValue);
-    }
-
-    /**
-     * Returns the minimum number of digits allowed in the fraction portion of a
-     * number.  The default value is 0, which subclasses can override.
-     * When formatting, if this value is not reached, numbers are padded on
-     * the right with the locale-specific '0' character to ensure at least
-     * this number of fraction digits.  When parsing, this has no effect.
-     * @return the minimum number of fraction digits
-     * @see #setMinimumFractionDigits
-     * @stable ICU 2.0
-     */
-    public int getMinimumFractionDigits() {
-        return numberFormat.getMinimumFractionDigits();
-    }
-
-    /**
-     * Sets the minimum number of digits allowed in the fraction portion of a
-     * number.  This must be <= maximumFractionDigits.  If the
-     * new value for minimumFractionDigits exceeds the current value
-     * of maximumFractionDigits, then maximumFractionDigits will also be set to
-     * the new value.
-     * @param newValue the minimum number of fraction digits to be shown; if
-     * less than zero, then zero is used.  Subclasses might enforce an
-     * upper limit to this value appropriate to the numeric type being formatted.
-     * @see #getMinimumFractionDigits
-     * @stable ICU 2.0
-     */
-    public void setMinimumFractionDigits(int newValue) {
-        numberFormat.setMinimumFractionDigits(newValue);
-    }
-
-    /**
-     * Sets the <tt>Currency</tt> object used to display currency
-     * amounts.  This takes effect immediately, if this format is a
-     * currency format.  If this format is not a currency format, then
-     * the currency object is used if and when this object becomes a
-     * currency format.
-     * @param theCurrency new currency object to use.  May be null for
-     * some subclasses.
-     * @stable ICU 2.6
-     */
-    public void setCurrency(Currency theCurrency) {
-        numberFormat.setCurrency(theCurrency.currency);
-    }
-
-    /**
-     * Returns the <tt>Currency</tt> object used to display currency
-     * amounts.  This may be null.
-     * @stable ICU 2.6
-     */
-    public Currency getCurrency() {
-        return new Currency(numberFormat.getCurrency());
-    }
-
-    /**
-     * Returns the rounding mode used in this NumberFormat.  The default implementation of
-     * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.
-     * @return A rounding mode, between <code>BigDecimal.ROUND_UP</code>
-     * and <code>BigDecimal.ROUND_UNNECESSARY</code>.
-     * @see #setRoundingMode(int)
-     * @stable ICU 4.0
-     */
-    public int getRoundingMode() {
-        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-    }
-
-    /**
-     * Set the rounding mode used in this NumberFormat.  The default implementation of
-     * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.
-     * @param roundingMode A rounding mode, between
-     * <code>BigDecimal.ROUND_UP</code> and
-     * <code>BigDecimal.ROUND_UNNECESSARY</code>.
-     * @see #getRoundingMode()
-     * @stable ICU 4.0
-     */
-    public void setRoundingMode(int roundingMode) {
-        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-    }
-
-
-    /**
-     * Returns a specific style number format for a specific locale.
-     * @param desiredLocale  the specific locale.
-     * @param choice         number format style
-     * @throws IllegalArgumentException  if choice is not one of
-     *                                   NUMBERSTYLE, CURRENCYSTYLE,
-     *                                   PERCENTSTYLE, SCIENTIFICSTYLE,
-     *                                   INTEGERSTYLE,
-     *                                   ISOCURRENCYSTYLE, PLURALCURRENCYSTYLE,
-     * @stable ICU 4.2
-     */
-    public static NumberFormat getInstance(ULocale desiredLocale, int choice) {
-        Locale locale = desiredLocale.toLocale();
-        java.text.NumberFormat nf = null;
-        switch (choice) {
-        case NUMBERSTYLE:
-            nf = java.text.NumberFormat.getInstance(locale);
-            break;
-        case INTEGERSTYLE:
-            nf = java.text.NumberFormat.getIntegerInstance(locale);
-            break;
-        case CURRENCYSTYLE:
-            nf = java.text.NumberFormat.getCurrencyInstance(locale);
-            break;
-        case PERCENTSTYLE:
-            nf = java.text.NumberFormat.getPercentInstance(locale);
-            break;
-        case SCIENTIFICSTYLE:
-            nf = new java.text.DecimalFormat("#E0",
-                    new java.text.DecimalFormatSymbols(locale));
-            nf.setMaximumFractionDigits(10);
-            break;
-        }
-        return new NumberFormat(nf);
-    }
-
-    /**
-     * Empty constructor.  Public for compatibility with JDK which lets the
-     * compiler generate a default public constructor even though this is
-     * an abstract class.
-     * @stable ICU 2.6
-     */
-    public NumberFormat() {
-        this(java.text.NumberFormat.getInstance(ULocale.getDefault(Category.FORMAT).toLocale()));
-    }
-
-    /**
-     * The instances of this inner class are used as attribute keys and values
-     * in AttributedCharacterIterator that
-     * NumberFormat.formatToCharacterIterator() method returns.
-     * <p>
-     * There is no public constructor to this class, the only instances are the
-     * constants defined here.
-     * <p>
-     * @stable ICU 3.6
-     */
-    public static class Field extends Format.Field {
-        // generated by serialver from JDK 1.4.1_01
-        static final long serialVersionUID = -4516273749929385842L;
-
-        /**
-         * @stable ICU 3.6
-         */
-        public static final Field SIGN = new Field("sign");
-
-        /**
-         * @stable ICU 3.6
-         */
-        public static final Field INTEGER = new Field("integer");
-
-        /**
-         * @stable ICU 3.6
-         */
-        public static final Field FRACTION = new Field("fraction");
-
-        /**
-         * @stable ICU 3.6
-         */
-        public static final Field EXPONENT = new Field("exponent");
-
-        /**
-         * @stable ICU 3.6
-         */
-        public static final Field EXPONENT_SIGN = new Field("exponent sign");
-
-        /**
-         * @stable ICU 3.6
-         */
-        public static final Field EXPONENT_SYMBOL = new Field("exponent symbol");
-
-        /**
-         * @stable ICU 3.6
-         */
-        public static final Field DECIMAL_SEPARATOR = new Field("decimal separator");
-        /**
-         * @stable ICU 3.6
-         */
-        public static final Field GROUPING_SEPARATOR = new Field("grouping separator");
-
-        /**
-         * @stable ICU 3.6
-         */
-        public static final Field PERCENT = new Field("percent");
-
-        /**
-         * @stable ICU 3.6
-         */
-        public static final Field PERMILLE = new Field("per mille");
-
-        /**
-         * @stable ICU 3.6
-         */
-        public static final Field CURRENCY = new Field("currency");
-
-        /**
-         * Constructs a new instance of NumberFormat.Field with the given field
-         * name.
-         * @stable ICU 3.6
-         */
-        protected Field(String fieldName) {
-            super(fieldName);
-        }
-
-        /**
-         * serizalization method resolve instances to the constant
-         * NumberFormat.Field values
-         * @stable ICU 3.6
-         */
-        protected Object readResolve() throws InvalidObjectException {
-            if (this.getName().equals(INTEGER.getName()))
-                return INTEGER;
-            if (this.getName().equals(FRACTION.getName()))
-                return FRACTION;
-            if (this.getName().equals(EXPONENT.getName()))
-                return EXPONENT;
-            if (this.getName().equals(EXPONENT_SIGN.getName()))
-                return EXPONENT_SIGN;
-            if (this.getName().equals(EXPONENT_SYMBOL.getName()))
-                return EXPONENT_SYMBOL;
-            if (this.getName().equals(CURRENCY.getName()))
-                return CURRENCY;
-            if (this.getName().equals(DECIMAL_SEPARATOR.getName()))
-                return DECIMAL_SEPARATOR;
-            if (this.getName().equals(GROUPING_SEPARATOR.getName()))
-                return GROUPING_SEPARATOR;
-            if (this.getName().equals(PERCENT.getName()))
-                return PERCENT;
-            if (this.getName().equals(PERMILLE.getName()))
-                return PERMILLE;
-            if (this.getName().equals(SIGN.getName()))
-                return SIGN;
-
-            throw new InvalidObjectException("An invalid object.");
-        }
-    }
-
-    private static FieldPosition toJDKFieldPosition(FieldPosition icuPos) {
-        if (icuPos == null) {
-            return null;
-        }
-
-        int fieldID = icuPos.getField();
-        Format.Field fieldAttribute = icuPos.getFieldAttribute();
-
-        FieldPosition jdkPos = null;
-
-        if (fieldID >= 0) {
-            if (fieldID == FRACTION_FIELD) {
-                fieldID = java.text.NumberFormat.FRACTION_FIELD;
-            } else if (fieldID == INTEGER_FIELD) {
-                fieldID = java.text.NumberFormat.INTEGER_FIELD;
-            }
-        }
-
-        if (fieldAttribute != null) {
-            // map field
-            if (fieldAttribute.equals(Field.CURRENCY)) {
-                fieldAttribute = java.text.NumberFormat.Field.CURRENCY;
-            } else if (fieldAttribute.equals(Field.DECIMAL_SEPARATOR)) {
-                fieldAttribute = java.text.NumberFormat.Field.DECIMAL_SEPARATOR;
-            } else if (fieldAttribute.equals(Field.EXPONENT)) {
-                fieldAttribute = java.text.NumberFormat.Field.EXPONENT;
-            } else if (fieldAttribute.equals(Field.EXPONENT_SIGN)) {
-                fieldAttribute = java.text.NumberFormat.Field.EXPONENT_SIGN;
-            } else if (fieldAttribute.equals(Field.EXPONENT_SYMBOL)) {
-                fieldAttribute = java.text.NumberFormat.Field.EXPONENT_SYMBOL;
-            } else if (fieldAttribute.equals(Field.FRACTION)) {
-                fieldAttribute = java.text.NumberFormat.Field.FRACTION;
-            } else if (fieldAttribute.equals(Field.GROUPING_SEPARATOR)) {
-                fieldAttribute = java.text.NumberFormat.Field.GROUPING_SEPARATOR;
-            } else if (fieldAttribute.equals(Field.INTEGER)) {
-                fieldAttribute = java.text.NumberFormat.Field.INTEGER;
-            } else if (fieldAttribute.equals(Field.PERCENT)) {
-                fieldAttribute = java.text.NumberFormat.Field.PERCENT;
-            } else if (fieldAttribute.equals(Field.PERMILLE)) {
-                fieldAttribute = java.text.NumberFormat.Field.PERMILLE;
-            } else if (fieldAttribute.equals(Field.SIGN)) {
-                fieldAttribute = java.text.NumberFormat.Field.SIGN;
-            }
-
-            jdkPos = new FieldPosition(fieldAttribute, fieldID);
-        } else {
-            jdkPos = new FieldPosition(fieldID);
-        }
-
-        jdkPos.setBeginIndex(icuPos.getBeginIndex());
-        jdkPos.setEndIndex(icuPos.getEndIndex());
-
-        return jdkPos;
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/SimpleDateFormat.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/SimpleDateFormat.java
deleted file mode 100644
index 45fa417..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/SimpleDateFormat.java
+++ /dev/null
@@ -1,540 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 1996-2012, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-
-package com.ibm.icu.text;
-
-import java.text.AttributedCharacterIterator;
-import java.text.AttributedCharacterIterator.Attribute;
-import java.text.AttributedString;
-import java.text.CharacterIterator;
-import java.text.FieldPosition;
-import java.text.ParsePosition;
-import java.util.Date;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import com.ibm.icu.util.Calendar;
-import com.ibm.icu.util.ULocale;
-
-
-/**
- * {@icuenhanced java.text.SimpleDateFormat}.{@icu _usage_}
- *
- * <p><code>SimpleDateFormat</code> is a concrete class for formatting and
- * parsing dates in a locale-sensitive manner. It allows for formatting
- * (date -> text), parsing (text -> date), and normalization.
- *
- * <p>
- * <code>SimpleDateFormat</code> allows you to start by choosing
- * any user-defined patterns for date-time formatting. However, you
- * are encouraged to create a date-time formatter with either
- * <code>getTimeInstance</code>, <code>getDateInstance</code>, or
- * <code>getDateTimeInstance</code> in <code>DateFormat</code>. Each
- * of these class methods can return a date/time formatter initialized
- * with a default format pattern. You may modify the format pattern
- * using the <code>applyPattern</code> methods as desired.
- * For more information on using these methods, see
- * {@link DateFormat}.
- *
- * <p>
- * <strong>Time Format Syntax:</strong>
- * <p>
- * To specify the time format use a <em>time pattern</em> string.
- * In this pattern, all ASCII letters are reserved as pattern letters,
- * which are defined as the following:
- * <blockquote>
- * <pre>
- * Symbol   Meaning                 Presentation        Example
- * ------   -------                 ------------        -------
- * G        era designator          (Text)              AD
- * y&#x2020;       year                    (Number)            1996
- * Y*       year (week of year)     (Number)            1997
- * u*       extended year           (Number)            4601
- * M        month in year           (Text & Number)     July & 07
- * d        day in month            (Number)            10
- * h        hour in am/pm (1~12)    (Number)            12
- * H        hour in day (0~23)      (Number)            0
- * m        minute in hour          (Number)            30
- * s        second in minute        (Number)            55
- * S        fractional second       (Number)            978
- * E        day of week             (Text)              Tuesday
- * e*       day of week (local 1~7) (Text & Number)     Tuesday & 2
- * D        day in year             (Number)            189
- * F        day of week in month    (Number)            2 (2nd Wed in July)
- * w        week in year            (Number)            27
- * W        week in month           (Number)            2
- * a        am/pm marker            (Text)              PM
- * k        hour in day (1~24)      (Number)            24
- * K        hour in am/pm (0~11)    (Number)            0
- * z        time zone               (Text)              Pacific Standard Time
- * Z        time zone (RFC 822)     (Number)            -0800
- * v        time zone (generic)     (Text)              Pacific Time
- * V        time zone (location)    (Text)              United States (Los Angeles)
- * g*       Julian day              (Number)            2451334
- * A*       milliseconds in day     (Number)            69540000
- * Q*       quarter in year         (Text & Number)     Q1 & 01
- * c*       stand alone day of week (Text & Number)     Tuesday & 2
- * L*       stand alone month       (Text & Number)     July & 07
- * q*       stand alone quarter     (Text & Number)     Q1 & 01
- * '        escape for text         (Delimiter)         'Date='
- * ''       single quote            (Literal)           'o''clock'
- * </pre>
- * </blockquote>
- * <tt><b>*</b></tt> These items are not supported by Java's SimpleDateFormat.<br>
- * <tt><b>&#x2020;</b></tt> ICU interprets a single 'y' differently than Java.</p>
- * <p>
- * The count of pattern letters determine the format.
- * <p>
- * <strong>(Text)</strong>: 4 or more pattern letters--use full form,
- * &lt; 4--use short or abbreviated form if one exists.
- * <p>
- * <strong>(Number)</strong>: the minimum number of digits. Shorter
- * numbers are zero-padded to this amount. Year is handled specially;
- * that is, if the count of 'y' is 2, the Year will be truncated to 2 digits.
- * (e.g., if "yyyy" produces "1997", "yy" produces "97".)
- * Unlike other fields, fractional seconds are padded on the right with zero.
- * <p>
- * <strong>(Text & Number)</strong>: 3 or over, use text, otherwise use number.
- * <p>
- * Any characters in the pattern that are not in the ranges of ['a'..'z']
- * and ['A'..'Z'] will be treated as quoted text. For instance, characters
- * like ':', '.', ' ', '#' and '@' will appear in the resulting time text
- * even they are not embraced within single quotes.
- * <p>
- * A pattern containing any invalid pattern letter will result in a thrown
- * exception during formatting or parsing.
- *
- * <p>
- * <strong>Examples Using the US Locale:</strong>
- * <blockquote>
- * <pre>
- * Format Pattern                         Result
- * --------------                         -------
- * "yyyy.MM.dd G 'at' HH:mm:ss vvvv" ->>  1996.07.10 AD at 15:08:56 Pacific Time
- * "EEE, MMM d, ''yy"                ->>  Wed, July 10, '96
- * "h:mm a"                          ->>  12:08 PM
- * "hh 'o''clock' a, zzzz"           ->>  12 o'clock PM, Pacific Daylight Time
- * "K:mm a, vvv"                     ->>  0:00 PM, PT
- * "yyyyy.MMMMM.dd GGG hh:mm aaa"    ->>  01996.July.10 AD 12:08 PM
- * </pre>
- * </blockquote>
- * <strong>Code Sample:</strong>
- * <blockquote>
- * <pre>
- * SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, "PST");
- * pdt.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2*60*60*1000);
- * pdt.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*60*60*1000);
- * <br>
- * // Format the current time.
- * SimpleDateFormat formatter
- *     = new SimpleDateFormat ("yyyy.MM.dd G 'at' hh:mm:ss a zzz");
- * Date currentTime_1 = new Date();
- * String dateString = formatter.format(currentTime_1);
- * <br>
- * // Parse the previous string back into a Date.
- * ParsePosition pos = new ParsePosition(0);
- * Date currentTime_2 = formatter.parse(dateString, pos);
- * </pre>
- * </blockquote>
- * In the example, the time value <code>currentTime_2</code> obtained from
- * parsing will be equal to <code>currentTime_1</code>. However, they may not be
- * equal if the am/pm marker 'a' is left out from the format pattern while
- * the "hour in am/pm" pattern symbol is used. This information loss can
- * happen when formatting the time in PM.
- *
- * <p>When parsing a date string using the abbreviated year pattern ("yy"),
- * SimpleDateFormat must interpret the abbreviated year
- * relative to some century.  It does this by adjusting dates to be
- * within 80 years before and 20 years after the time the SimpleDateFormat
- * instance is created. For example, using a pattern of "MM/dd/yy" and a
- * SimpleDateFormat instance created on Jan 1, 1997,  the string
- * "01/11/12" would be interpreted as Jan 11, 2012 while the string "05/04/64"
- * would be interpreted as May 4, 1964.
- * During parsing, only strings consisting of exactly two digits, as defined by
- * {@link com.ibm.icu.lang.UCharacter#isDigit(int)}, will be parsed into the default
- * century.
- * Any other numeric string, such as a one digit string, a three or more digit
- * string, or a two digit string that isn't all digits (for example, "-1"), is
- * interpreted literally.  So "01/02/3" or "01/02/003" are parsed, using the
- * same pattern, as Jan 2, 3 AD.  Likewise, "01/02/-3" is parsed as Jan 2, 4 BC.
- *
- * <p>If the year pattern does not have exactly two 'y' characters, the year is
- * interpreted literally, regardless of the number of digits.  So using the
- * pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D.
- *
- * <p>When numeric fields abut one another directly, with no intervening delimiter
- * characters, they constitute a run of abutting numeric fields.  Such runs are
- * parsed specially.  For example, the format "HHmmss" parses the input text
- * "123456" to 12:34:56, parses the input text "12345" to 1:23:45, and fails to
- * parse "1234".  In other words, the leftmost field of the run is flexible,
- * while the others keep a fixed width.  If the parse fails anywhere in the run,
- * then the leftmost field is shortened by one character, and the entire run is
- * parsed again. This is repeated until either the parse succeeds or the
- * leftmost field is one character in length.  If the parse still fails at that
- * point, the parse of the run fails.
- *
- * <p>For time zones that have no names, use strings GMT+hours:minutes or
- * GMT-hours:minutes.
- *
- * <p>The calendar defines what is the first day of the week, the first week
- * of the year, whether hours are zero based or not (0 vs 12 or 24), and the
- * time zone. There is one common decimal format to handle all the numbers;
- * the digit count is handled programmatically according to the pattern.
- *
- * <h4>Synchronization</h4>
- *
- * Date formats are not synchronized. It is recommended to create separate
- * format instances for each thread. If multiple threads access a format
- * concurrently, it must be synchronized externally.
- *
- * @see          com.ibm.icu.util.Calendar
- * @see          com.ibm.icu.util.GregorianCalendar
- * @see          com.ibm.icu.util.TimeZone
- * @see          DateFormat
- * @see          DateFormatSymbols
- * @see          DecimalFormat
- * @author       Mark Davis, Chen-Lieh Huang, Alan Liu
- * @stable ICU 2.0
- */
-public class SimpleDateFormat extends DateFormat {
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * Constructs a SimpleDateFormat using the default pattern for the default
-     * locale.  <b>Note:</b> Not all locales support SimpleDateFormat; for full
-     * generality, use the factory methods in the DateFormat class.
-     *
-     * @see DateFormat
-     * @stable ICU 2.0
-     */
-    public SimpleDateFormat() {
-        super(new java.text.SimpleDateFormat());
-    }
-
-    /**
-     * Constructs a SimpleDateFormat using the given pattern in the default
-     * locale.  <b>Note:</b> Not all locales support SimpleDateFormat; for full
-     * generality, use the factory methods in the DateFormat class.
-     * @stable ICU 2.0
-     */
-    public SimpleDateFormat(String pattern)
-    {
-        super(new java.text.SimpleDateFormat(pattern));
-    }
-
-    /**
-     * Constructs a SimpleDateFormat using the given pattern and locale.
-     * <b>Note:</b> Not all locales support SimpleDateFormat; for full
-     * generality, use the factory methods in the DateFormat class.
-     * @stable ICU 2.0
-     */
-    public SimpleDateFormat(String pattern, Locale loc)
-    {
-        super(new java.text.SimpleDateFormat(pattern, loc));
-    }
-
-    /**
-     * Constructs a SimpleDateFormat using the given pattern and locale.
-     * <b>Note:</b> Not all locales support SimpleDateFormat; for full
-     * generality, use the factory methods in the DateFormat class.
-     * @stable ICU 3.2
-     */
-    public SimpleDateFormat(String pattern, ULocale loc)
-    {
-        this(pattern, loc.toLocale());
-    }
-
-//    /**
-//     * Constructs a SimpleDateFormat using the given pattern , override and locale.
-//     * @param pattern The pattern to be used
-//     * @param override The override string.  A numbering system override string can take one of the following forms:
-//     *     1). If just a numbering system name is specified, it applies to all numeric fields in the date format pattern.
-//     *     2). To specify an alternate numbering system on a field by field basis, use the field letters from the pattern
-//     *         followed by an = sign, followed by the numbering system name.  For example, to specify that just the year
-//     *         be formatted using Hebrew digits, use the override "y=hebr".  Multiple overrides can be specified in a single
-//     *         string by separating them with a semi-colon. For example, the override string "m=thai;y=deva" would format using
-//     *         Thai digits for the month and Devanagari digits for the year.
-//     * @param loc The locale to be used
-//     * @stable ICU 4.2
-//     */
-//    public SimpleDateFormat(String pattern, String override, ULocale loc)
-//    {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Constructs a SimpleDateFormat using the given pattern and
-     * locale-specific symbol data.
-     * Warning: uses default locale for digits!
-     * @stable ICU 2.0
-     */
-    public SimpleDateFormat(String pattern, DateFormatSymbols formatData)
-    {
-        super(new java.text.SimpleDateFormat(pattern, formatData.dfs));
-    }
-
-    /**
-     * Sets the 100-year period 2-digit years will be interpreted as being in
-     * to begin on the date the user specifies.
-     * @param startDate During parsing, two digit years will be placed in the range
-     * <code>startDate</code> to <code>startDate + 100 years</code>.
-     * @stable ICU 2.0
-     */
-    public void set2DigitYearStart(Date startDate) {
-        ((java.text.SimpleDateFormat)dateFormat).set2DigitYearStart(startDate);
-    }
-
-    /**
-     * Returns the beginning date of the 100-year period 2-digit years are interpreted
-     * as being within.
-     * @return the start of the 100-year period into which two digit years are
-     * parsed
-     * @stable ICU 2.0
-     */
-    public Date get2DigitYearStart() {
-        return ((java.text.SimpleDateFormat)dateFormat).get2DigitYearStart();
-    }
-
-    /**
-     * Formats a date or time, which is the standard millis
-     * since January 1, 1970, 00:00:00 GMT.
-     * <p>Example: using the US locale:
-     * "yyyy.MM.dd G 'at' HH:mm:ss zzz" ->> 1996.07.10 AD at 15:08:56 PDT
-     * @param cal the calendar whose date-time value is to be formatted into a date-time string
-     * @param toAppendTo where the new date-time text is to be appended
-     * @param pos the formatting position. On input: an alignment field,
-     * if desired. On output: the offsets of the alignment field.
-     * @return the formatted date-time string.
-     * @see DateFormat
-     * @stable ICU 2.0
-     */
-    public StringBuffer format(Calendar cal, StringBuffer toAppendTo,
-                               FieldPosition pos) {
-        StringBuffer result;
-        FieldPosition jdkPos = toJDKFieldPosition(pos);
-        synchronized(dateFormat) {
-            java.util.Calendar oldCal = dateFormat.getCalendar();
-            dateFormat.setCalendar(cal.calendar);
-            result = dateFormat.format(cal.getTime(), toAppendTo, jdkPos);
-            dateFormat.setCalendar(oldCal);
-        }
-        if (jdkPos != null) {
-            pos.setBeginIndex(jdkPos.getBeginIndex());
-            pos.setEndIndex(jdkPos.getEndIndex());
-        }
-        return result;
-    }
-
-    /**
-     * Overrides superclass method
-     * @stable ICU 2.0
-     */
-    public void setNumberFormat(NumberFormat newNumberFormat) {
-        super.setNumberFormat(newNumberFormat);
-    }
-
-    /**
-     * Overrides DateFormat
-     * @see DateFormat
-     * @stable ICU 2.0
-     */
-    public void parse(String text, Calendar cal, ParsePosition parsePos)
-    {
-        // Note: parsed time zone won't be set in the result calendar
-        cal.setTime(dateFormat.parse(text, parsePos));
-    }
-
-    /**
-     * Return a pattern string describing this date format.
-     * @stable ICU 2.0
-     */
-    public String toPattern() {
-        return ((java.text.SimpleDateFormat)dateFormat).toPattern();
-    }
-
-    /**
-     * Return a localized pattern string describing this date format.
-     * @stable ICU 2.0
-     */
-    public String toLocalizedPattern() {
-        return ((java.text.SimpleDateFormat)dateFormat).toLocalizedPattern();
-    }
-
-    /**
-     * Apply the given unlocalized pattern string to this date format.
-     * @stable ICU 2.0
-     */
-    public void applyPattern(String pat) {
-        ((java.text.SimpleDateFormat)dateFormat).applyPattern(pat);
-    }
-
-    /**
-     * Apply the given localized pattern string to this date format.
-     * @stable ICU 2.0
-     */
-    public void applyLocalizedPattern(String pat) {
-        ((java.text.SimpleDateFormat)dateFormat).applyLocalizedPattern(pat);
-    }
-
-    /**
-     * Gets the date/time formatting data.
-     * @return a copy of the date-time formatting data associated
-     * with this date-time formatter.
-     * @stable ICU 2.0
-     */
-    public DateFormatSymbols getDateFormatSymbols() {
-        return new DateFormatSymbols(((java.text.SimpleDateFormat)dateFormat).getDateFormatSymbols());
-    }
-
-    /**
-     * Allows you to set the date/time formatting data.
-     * @param newFormatSymbols the new symbols
-     * @stable ICU 2.0
-     */
-    public void setDateFormatSymbols(DateFormatSymbols newFormatSymbols) {
-        ((java.text.SimpleDateFormat)dateFormat).setDateFormatSymbols(newFormatSymbols.dfs);
-    }
-
-//    /**
-//     * {@icu} Gets the time zone formatter which this date/time
-//     * formatter uses to format and parse a time zone.
-//     * 
-//     * @return the time zone formatter which this date/time
-//     * formatter uses.
-//     * @draft ICU 49
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public TimeZoneFormat getTimeZoneFormat() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Allows you to set the time zone formatter.
-//     * 
-//     * @param tzfmt the new time zone formatter
-//     * @draft ICU 49
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public void setTimeZoneFormat(TimeZoneFormat tzfmt) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    // For clone to use
-    private SimpleDateFormat(java.text.SimpleDateFormat sdf) {
-        super(sdf);
-    }
-
-    /**
-     * Overrides Cloneable
-     * @stable ICU 2.0
-     */
-    public Object clone() {
-        return new SimpleDateFormat((java.text.SimpleDateFormat)dateFormat.clone());
-    }
-
-    /**
-     * Override hashCode.
-     * Generates the hash code for the SimpleDateFormat object
-     * @stable ICU 2.0
-     */
-    public int hashCode()
-    {
-        return super.hashCode();
-    }
-
-    /**
-     * Override equals.
-     * @stable ICU 2.0
-     */
-    public boolean equals(Object obj)
-    {
-        return super.equals(obj);
-    }
-
-    /**
-     * Format the object to an attributed string, and return the corresponding iterator
-     * Overrides superclass method.
-     *
-     * @param obj The object to format
-     * @return <code>AttributedCharacterIterator</code> describing the formatted value.
-     *
-     * @stable ICU 3.8
-     */
-    public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
-        AttributedCharacterIterator it = dateFormat.formatToCharacterIterator(obj);
-
-        // Extract formatted String first
-        StringBuilder sb = new StringBuilder();
-        for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
-            sb.append(c);
-        }
-
-        // Create AttributedString
-        AttributedString attrstr = new AttributedString(sb.toString());
-
-        // Map JDK Field to ICU Field
-        int idx = 0;
-        it.first();
-        while (idx < it.getEndIndex()) {
-            int end = it.getRunLimit();
-            Map<Attribute, Object> attributes = it.getAttributes();
-            if (attributes != null) {
-                for (Entry<Attribute, Object> entry : attributes.entrySet()) {
-                    Attribute attr = entry.getKey();
-                    Object val = entry.getValue();
-                    if (attr.equals(java.text.DateFormat.Field.AM_PM)) {
-                        val = attr = Field.AM_PM;
-                    } else if (attr.equals(java.text.DateFormat.Field.DAY_OF_MONTH)) {
-                        val = attr = Field.DAY_OF_MONTH;
-                    } else if (attr.equals(java.text.DateFormat.Field.DAY_OF_WEEK)) {
-                        val = attr = Field.DAY_OF_WEEK ;
-                    } else if (attr.equals(java.text.DateFormat.Field.DAY_OF_WEEK_IN_MONTH)) {
-                        val = attr = Field.DAY_OF_WEEK_IN_MONTH ;
-                    } else if (attr.equals(java.text.DateFormat.Field.DAY_OF_YEAR)) {
-                        val = attr = Field.DAY_OF_YEAR;
-                    } else if (attr.equals(java.text.DateFormat.Field.ERA)) {
-                        val = attr = Field.ERA;
-                    } else if (attr.equals(java.text.DateFormat.Field.HOUR_OF_DAY0)) {
-                        val = attr = Field.HOUR_OF_DAY0;
-                    } else if (attr.equals(java.text.DateFormat.Field.HOUR_OF_DAY1)) {
-                        val = attr = Field.HOUR_OF_DAY1;
-                    } else if (attr.equals(java.text.DateFormat.Field.HOUR0)) {
-                        val = attr = Field.HOUR0;
-                    } else if (attr.equals(java.text.DateFormat.Field.HOUR1)) {
-                        val = attr = Field.HOUR1;
-                    } else if (attr.equals(java.text.DateFormat.Field.MILLISECOND)) {
-                        val = attr = Field.MILLISECOND;
-                    } else if (attr.equals(java.text.DateFormat.Field.MINUTE)) {
-                        val = attr = Field.MINUTE;
-                    } else if (attr.equals(java.text.DateFormat.Field.MONTH)) {
-                        val = attr = Field.MONTH;
-                    } else if (attr.equals(java.text.DateFormat.Field.SECOND)) {
-                        val = attr = Field.SECOND;
-                    } else if (attr.equals(java.text.DateFormat.Field.TIME_ZONE)) {
-                        val = attr = Field.TIME_ZONE;
-                    } else if (attr.equals(java.text.DateFormat.Field.WEEK_OF_MONTH)) {
-                        val = attr = Field.WEEK_OF_MONTH;
-                    } else if (attr.equals(java.text.DateFormat.Field.WEEK_OF_YEAR)) {
-                        val = attr = Field.WEEK_OF_YEAR;
-                    } else if (attr.equals(java.text.DateFormat.Field.YEAR)) {
-                        val = attr = Field.YEAR;
-                    }
-                    attrstr.addAttribute(attr, val, idx, end);
-                }
-            }
-            idx = end;
-            while (it.getIndex() < idx) {
-                it.next();
-            }
-        }
-
-        return attrstr.getIterator();
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/UFormat.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/UFormat.java
deleted file mode 100644
index 1b024c1..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/text/UFormat.java
+++ /dev/null
@@ -1,80 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2003-2012, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.text;
-
-import java.text.Format;
-
-/**
- * An abstract class that extends {@link java.text.Format} to provide
- * additional ICU protocol, specifically, the <tt>getLocale()</tt>
- * API.  All ICU format classes are subclasses of this class.
- *
- * @see com.ibm.icu.util.ULocale
- * @author weiv
- * @author Alan Liu
- * @draft ICU 2.8 (retain)
- * @provisional This API might change or be removed in a future release.
- */
-public abstract class UFormat extends Format {
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * @draft ICU 2.8 (retain)
-     * @provisional This API might change or be removed in a future release.
-     */
-    public UFormat() {}
-
-//    /**
-//     * Return the locale that was used to create this object, or null.
-//     * This may may differ from the locale requested at the time of
-//     * this object's creation.  For example, if an object is created
-//     * for locale <tt>en_US_CALIFORNIA</tt>, the actual data may be
-//     * drawn from <tt>en</tt> (the <i>actual</i> locale), and
-//     * <tt>en_US</tt> may be the most specific locale that exists (the
-//     * <i>valid</i> locale).
-//     *
-//     * <p>Note: This method will be implemented in ICU 3.0; ICU 2.8
-//     * contains a partial preview implementation.  The <i>actual</i>
-//     * locale is returned correctly, but the <i>valid</i> locale is
-//     * not, in most cases.
-//     * @param type type of information requested, either {@link
-//     * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link
-//     * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}.
-//     * @return the information specified by <i>type</i>, or null if
-//     * this object was not constructed from locale data.
-//     * @see com.ibm.icu.util.ULocale
-//     * @see com.ibm.icu.util.ULocale#VALID_LOCALE
-//     * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
-//     * @draft ICU 2.8 (retain)
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public final ULocale getLocale(ULocale.Type type) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Set information about the locales that were used to create this
-//     * object.  If the object was not constructed from locale data,
-//     * both arguments should be set to null.  Otherwise, neither
-//     * should be null.  The actual locale must be at the same level or
-//     * less specific than the valid locale.  This method is intended
-//     * for use by factories or other entities that create objects of
-//     * this class.
-//     * @param valid the most specific locale containing any resource
-//     * data, or null
-//     * @param actual the locale containing data used to construct this
-//     * object, or null
-//     * @see com.ibm.icu.util.ULocale
-//     * @see com.ibm.icu.util.ULocale#VALID_LOCALE
-//     * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
-//     */
-//    final void setLocale(ULocale valid, ULocale actual) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Calendar.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Calendar.java
deleted file mode 100644
index e11d5ca..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Calendar.java
+++ /dev/null
@@ -1,2484 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
-*   Copyright (C) 1996-2016, International Business Machines
-*   Corporation and others.  All Rights Reserved.
-*/
-
-package com.ibm.icu.util;
-
-import java.io.Serializable;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Locale;
-
-import com.ibm.icu.text.DateFormat;
-import com.ibm.icu.util.ULocale.Category;
-
-/**
- * {@icuenhanced java.util.Calendar}.{@icu _usage_}
- *
- * <p><code>Calendar</code> is an abstract base class for converting between
- * a <code>Date</code> object and a set of integer fields such as
- * <code>YEAR</code>, <code>MONTH</code>, <code>DAY</code>, <code>HOUR</code>,
- * and so on. (A <code>Date</code> object represents a specific instant in
- * time with millisecond precision. See
- * {@link Date}
- * for information about the <code>Date</code> class.)
- *
- * <p>Subclasses of <code>Calendar</code> interpret a <code>Date</code>
- * according to the rules of a specific calendar system.  ICU4J contains
- * several subclasses implementing different international calendar systems.
- *
- * <p>
- * Like other locale-sensitive classes, <code>Calendar</code> provides a
- * class method, <code>getInstance</code>, for getting a generally useful
- * object of this type. <code>Calendar</code>'s <code>getInstance</code> method
- * returns a calendar of a type appropriate to the locale, whose
- * time fields have been initialized with the current date and time:
- * <blockquote>
- * <pre>Calendar rightNow = Calendar.getInstance()</pre>
- * </blockquote>
- *
- * <p>When a <code>ULocale</code> is used by <code>getInstance</code>, its
- * '<code>calendar</code>' tag and value are retrieved if present.  If a recognized
- * value is supplied, a calendar is provided and configured as appropriate.
- * Currently recognized tags are "buddhist", "chinese", "coptic", "ethiopic",
- * "gregorian", "hebrew", "islamic", "islamic-civil", "japanese", and "roc".  For
- * example: <blockquote>
- * <pre>Calendar cal = Calendar.getInstance(new ULocale("en_US@calendar=japanese"));</pre>
- * </blockquote> will return an instance of JapaneseCalendar (using en_US conventions for
- * minimum days in first week, start day of week, et cetera).
- *
- * <p>A <code>Calendar</code> object can produce all the time field values
- * needed to implement the date-time formatting for a particular language and
- * calendar style (for example, Japanese-Gregorian, Japanese-Traditional).
- * <code>Calendar</code> defines the range of values returned by certain fields,
- * as well as their meaning.  For example, the first month of the year has value
- * <code>MONTH</code> == <code>JANUARY</code> for all calendars.  Other values
- * are defined by the concrete subclass, such as <code>ERA</code> and
- * <code>YEAR</code>.  See individual field documentation and subclass
- * documentation for details.
- *
- * <p>When a <code>Calendar</code> is <em>lenient</em>, it accepts a wider range
- * of field values than it produces.  For example, a lenient
- * <code>GregorianCalendar</code> interprets <code>MONTH</code> ==
- * <code>JANUARY</code>, <code>DAY_OF_MONTH</code> == 32 as February 1.  A
- * non-lenient <code>GregorianCalendar</code> throws an exception when given
- * out-of-range field settings.  When calendars recompute field values for
- * return by <code>get()</code>, they normalize them.  For example, a
- * <code>GregorianCalendar</code> always produces <code>DAY_OF_MONTH</code>
- * values between 1 and the length of the month.
- *
- * <p><code>Calendar</code> defines a locale-specific seven day week using two
- * parameters: the first day of the week and the minimal days in first week
- * (from 1 to 7).  These numbers are taken from the locale resource data when a
- * <code>Calendar</code> is constructed.  They may also be specified explicitly
- * through the API.
- *
- * <p>When setting or getting the <code>WEEK_OF_MONTH</code> or
- * <code>WEEK_OF_YEAR</code> fields, <code>Calendar</code> must determine the
- * first week of the month or year as a reference point.  The first week of a
- * month or year is defined as the earliest seven day period beginning on
- * <code>getFirstDayOfWeek()</code> and containing at least
- * <code>getMinimalDaysInFirstWeek()</code> days of that month or year.  Weeks
- * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow
- * it.  Note that the normalized numbering returned by <code>get()</code> may be
- * different.  For example, a specific <code>Calendar</code> subclass may
- * designate the week before week 1 of a year as week <em>n</em> of the previous
- * year.
- *
- * <p> When computing a <code>Date</code> from time fields, two special
- * circumstances may arise: there may be insufficient information to compute the
- * <code>Date</code> (such as only year and month but no day in the month), or
- * there may be inconsistent information (such as "Tuesday, July 15, 1996" --
- * July 15, 1996 is actually a Monday).
- *
- * <p><strong>Insufficient information.</strong> The calendar will use default
- * information to specify the missing fields. This may vary by calendar; for
- * the Gregorian calendar, the default for a field is the same as that of the
- * start of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc.
- *
- * <p><strong>Inconsistent information.</strong> If fields conflict, the calendar
- * will give preference to fields set more recently. For example, when
- * determining the day, the calendar will look for one of the following
- * combinations of fields.  The most recent combination, as determined by the
- * most recently set single field, will be used.
- *
- * <blockquote>
- * <pre>
- * MONTH + DAY_OF_MONTH
- * MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
- * MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
- * DAY_OF_YEAR
- * DAY_OF_WEEK + WEEK_OF_YEAR</pre>
- * </blockquote>
- *
- * For the time of day:
- *
- * <blockquote>
- * <pre>
- * HOUR_OF_DAY
- * AM_PM + HOUR</pre>
- * </blockquote>
- *
- * <p><strong>Note:</strong> for some non-Gregorian calendars, different
- * fields may be necessary for complete disambiguation. For example, a full
- * specification of the historial Arabic astronomical calendar requires year,
- * month, day-of-month <em>and</em> day-of-week in some cases.
- *
- * <p><strong>Note:</strong> There are certain possible ambiguities in
- * interpretation of certain singular times, which are resolved in the
- * following ways:
- * <ol>
- *     <li> 24:00:00 "belongs" to the following day. That is,
- *          23:59 on Dec 31, 1969 &lt; 24:00 on Jan 1, 1970 &lt; 24:01:00 on Jan 1, 1970
- *
- *     <li> Although historically not precise, midnight also belongs to "am",
- *          and noon belongs to "pm", so on the same day,
- *          12:00 am (midnight) &lt; 12:01 am, and 12:00 pm (noon) &lt; 12:01 pm
- * </ol>
- *
- * <p>The date or time format strings are not part of the definition of a
- * calendar, as those must be modifiable or overridable by the user at
- * runtime. Use {@link DateFormat}
- * to format dates.
- *
- * <p><strong>Field manipulation methods</strong></p>
- *
- * <p><code>Calendar</code> fields can be changed using three methods:
- * <code>set()</code>, <code>add()</code>, and <code>roll()</code>.</p>
- *
- * <p><strong><code>set(f, value)</code></strong> changes field
- * <code>f</code> to <code>value</code>.  In addition, it sets an
- * internal member variable to indicate that field <code>f</code> has
- * been changed. Although field <code>f</code> is changed immediately,
- * the calendar's milliseconds is not recomputed until the next call to
- * <code>get()</code>, <code>getTime()</code>, or
- * <code>getTimeInMillis()</code> is made. Thus, multiple calls to
- * <code>set()</code> do not trigger multiple, unnecessary
- * computations. As a result of changing a field using
- * <code>set()</code>, other fields may also change, depending on the
- * field, the field value, and the calendar system. In addition,
- * <code>get(f)</code> will not necessarily return <code>value</code>
- * after the fields have been recomputed. The specifics are determined by
- * the concrete calendar class.</p>
- *
- * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
- * originally set to August 31, 1999. Calling <code>set(Calendar.MONTH,
- * Calendar.SEPTEMBER)</code> sets the calendar to September 31,
- * 1999. This is a temporary internal representation that resolves to
- * October 1, 1999 if <code>getTime()</code>is then called. However, a
- * call to <code>set(Calendar.DAY_OF_MONTH, 30)</code> before the call to
- * <code>getTime()</code> sets the calendar to September 30, 1999, since
- * no recomputation occurs after <code>set()</code> itself.</p>
- *
- * <p><strong><code>add(f, delta)</code></strong> adds <code>delta</code>
- * to field <code>f</code>.  This is equivalent to calling <code>set(f,
- * get(f) + delta)</code> with two adjustments:</p>
- *
- * <blockquote>
- *   <p><strong>Add rule 1</strong>. The value of field <code>f</code>
- *   after the call minus the value of field <code>f</code> before the
- *   call is <code>delta</code>, modulo any overflow that has occurred in
- *   field <code>f</code>. Overflow occurs when a field value exceeds its
- *   range and, as a result, the next larger field is incremented or
- *   decremented and the field value is adjusted back into its range.</p>
- *
- *   <p><strong>Add rule 2</strong>. If a smaller field is expected to be
- *   invariant, but &nbsp; it is impossible for it to be equal to its
- *   prior value because of changes in its minimum or maximum after field
- *   <code>f</code> is changed, then its value is adjusted to be as close
- *   as possible to its expected value. A smaller field represents a
- *   smaller unit of time. <code>HOUR</code> is a smaller field than
- *   <code>DAY_OF_MONTH</code>. No adjustment is made to smaller fields
- *   that are not expected to be invariant. The calendar system
- *   determines what fields are expected to be invariant.</p>
- * </blockquote>
- *
- * <p>In addition, unlike <code>set()</code>, <code>add()</code> forces
- * an immediate recomputation of the calendar's milliseconds and all
- * fields.</p>
- *
- * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
- * originally set to August 31, 1999. Calling <code>add(Calendar.MONTH,
- * 13)</code> sets the calendar to September 30, 2000. <strong>Add rule
- * 1</strong> sets the <code>MONTH</code> field to September, since
- * adding 13 months to August gives September of the next year. Since
- * <code>DAY_OF_MONTH</code> cannot be 31 in September in a
- * <code>GregorianCalendar</code>, <strong>add rule 2</strong> sets the
- * <code>DAY_OF_MONTH</code> to 30, the closest possible value. Although
- * it is a smaller field, <code>DAY_OF_WEEK</code> is not adjusted by
- * rule 2, since it is expected to change when the month changes in a
- * <code>GregorianCalendar</code>.</p>
- *
- * <p><strong><code>roll(f, delta)</code></strong> adds
- * <code>delta</code> to field <code>f</code> without changing larger
- * fields. This is equivalent to calling <code>add(f, delta)</code> with
- * the following adjustment:</p>
- *
- * <blockquote>
- *   <p><strong>Roll rule</strong>. Larger fields are unchanged after the
- *   call. A larger field represents a larger unit of
- *   time. <code>DAY_OF_MONTH</code> is a larger field than
- *   <code>HOUR</code>.</p>
- * </blockquote>
- *
- * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
- * originally set to August 31, 1999. Calling <code>roll(Calendar.MONTH,
- * 8)</code> sets the calendar to April 30, <strong>1999</strong>.  Add
- * rule 1 sets the <code>MONTH</code> field to April. Using a
- * <code>GregorianCalendar</code>, the <code>DAY_OF_MONTH</code> cannot
- * be 31 in the month April. Add rule 2 sets it to the closest possible
- * value, 30. Finally, the <strong>roll rule</strong> maintains the
- * <code>YEAR</code> field value of 1999.</p>
- *
- * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
- * originally set to Sunday June 6, 1999. Calling
- * <code>roll(Calendar.WEEK_OF_MONTH, -1)</code> sets the calendar to
- * Tuesday June 1, 1999, whereas calling
- * <code>add(Calendar.WEEK_OF_MONTH, -1)</code> sets the calendar to
- * Sunday May 30, 1999. This is because the roll rule imposes an
- * additional constraint: The <code>MONTH</code> must not change when the
- * <code>WEEK_OF_MONTH</code> is rolled. Taken together with add rule 1,
- * the resultant date must be between Tuesday June 1 and Saturday June
- * 5. According to add rule 2, the <code>DAY_OF_WEEK</code>, an invariant
- * when changing the <code>WEEK_OF_MONTH</code>, is set to Tuesday, the
- * closest possible value to Sunday (where Sunday is the first day of the
- * week).</p>
- *
- * <p><strong>Usage model</strong>. To motivate the behavior of
- * <code>add()</code> and <code>roll()</code>, consider a user interface
- * component with increment and decrement buttons for the month, day, and
- * year, and an underlying <code>GregorianCalendar</code>. If the
- * interface reads January 31, 1999 and the user presses the month
- * increment button, what should it read? If the underlying
- * implementation uses <code>set()</code>, it might read March 3, 1999. A
- * better result would be February 28, 1999. Furthermore, if the user
- * presses the month increment button again, it should read March 31,
- * 1999, not March 28, 1999. By saving the original date and using either
- * <code>add()</code> or <code>roll()</code>, depending on whether larger
- * fields should be affected, the user interface can behave as most users
- * will intuitively expect.</p>
- *
- * <p><b>Note:</b> You should always use {@link #roll roll} and {@link #add add} rather
- * than attempting to perform arithmetic operations directly on the fields
- * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
- * to have fields with non-linear behavior, for example missing months
- * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
- * methods will take this into account, while simple arithmetic manipulations
- * may give invalid results.
- *
- * <p><big><big><b>Calendar Architecture in ICU4J</b></big></big></p>
- *
- * <p>Recently the implementation of <code>Calendar</code> has changed
- * significantly in order to better support subclassing. The original
- * <code>Calendar</code> class was designed to support subclassing, but
- * it had only one implemented subclass, <code>GregorianCalendar</code>.
- * With the implementation of several new calendar subclasses, including
- * the <code>BuddhistCalendar</code>, <code>ChineseCalendar</code>,
- * <code>HebrewCalendar</code>, <code>IslamicCalendar</code>, and
- * <code>JapaneseCalendar</code>, the subclassing API has been reworked
- * thoroughly. This section details the new subclassing API and other
- * ways in which <code>com.ibm.icu.util.Calendar</code> differs from
- * <code>java.util.Calendar</code>.
- * </p>
- *
- * <p><big><b>Changes</b></big></p>
- *
- * <p>Overview of changes between the classic <code>Calendar</code>
- * architecture and the new architecture.
- *
- * <ul>
- *
- *   <li>The <code>fields[]</code> array is <code>private</code> now
- *     instead of <code>protected</code>.  Subclasses must access it
- *     using the methods {@link #internalSet} and
- *     {@link #internalGet}.  <b>Motivation:</b> Subclasses should
- *     not directly access data members.</li>
- *
- *   <li>The <code>time</code> long word is <code>private</code> now
- *     instead of <code>protected</code>.  Subclasses may access it using
- *     the method {@link #internalGetTimeInMillis}, which does not
- *     provoke an update. <b>Motivation:</b> Subclasses should not
- *     directly access data members.</li>
- *
- *   <li>The scope of responsibility of subclasses has been drastically
- *     reduced. As much functionality as possible is implemented in the
- *     <code>Calendar</code> base class. As a result, it is much easier
- *     to subclass <code>Calendar</code>. <b>Motivation:</b> Subclasses
- *     should not have to reimplement common code. Certain behaviors are
- *     common across calendar systems: The definition and behavior of
- *     week-related fields and time fields, the arithmetic
- *     ({@link #add(int, int) add} and {@link #roll(int, int) roll}) behavior of many
- *     fields, and the field validation system.</li>
- *
- *   <li>The subclassing API has been completely redesigned.</li>
- *
- *   <li>The <code>Calendar</code> base class contains some Gregorian
- *     calendar algorithmic support that subclasses can use (specifically
- *     in {@link #handleComputeFields}).  Subclasses can use the
- *     methods <code>getGregorianXxx()</code> to obtain precomputed
- *     values. <b>Motivation:</b> This is required by all
- *     <code>Calendar</code> subclasses in order to implement consistent
- *     time zone behavior, and Gregorian-derived systems can use the
- *     already computed data.</li>
- *
- *   <li>The <code>FIELD_COUNT</code> constant has been removed. Use
- *     {@link #getFieldCount}.  In addition, framework API has been
- *     added to allow subclasses to define additional fields.
- *     <b>Motivation: </b>The number of fields is not constant across
- *     calendar systems.</li>
- *
- *   <li>The range of handled dates has been narrowed from +/-
- *     ~300,000,000 years to +/- ~5,000,000 years. In practical terms
- *     this should not affect clients. However, it does mean that client
- *     code cannot be guaranteed well-behaved results with dates such as
- *     <code>Date(Long.MIN_VALUE)</code> or
- *     <code>Date(Long.MAX_VALUE)</code>. Instead, the
- *     <code>Calendar</code> protected constants should be used.
- *     <b>Motivation:</b> With
- *     the addition of the {@link #JULIAN_DAY} field, Julian day
- *     numbers must be restricted to a 32-bit <code>int</code>.  This
- *     restricts the overall supported range. Furthermore, restricting
- *     the supported range simplifies the computations by removing
- *     special case code that was used to accommodate arithmetic overflow
- *     at millis near <code>Long.MIN_VALUE</code> and
- *     <code>Long.MAX_VALUE</code>.</li>
- *
- *   <li>New fields are implemented: {@link #JULIAN_DAY} defines
- *     single-field specification of the
- *     date. {@link #MILLISECONDS_IN_DAY} defines a single-field
- *     specification of the wall time. {@link #DOW_LOCAL} and
- *     {@link #YEAR_WOY} implement localized day-of-week and
- *     week-of-year behavior.</li>
- *
- *   <li>Subclasses can access protected millisecond constants
- *   defined in <code>Calendar</code>.</li>
- *
- *   <li>New API has been added to support calendar-specific subclasses
- *     of <code>DateFormat</code>.</li>
- *
- *   <li>Several subclasses have been implemented, representing
- *     various international calendar systems.</li>
- *
- * </ul>
- *
- * <p><big><b>Subclass API</b></big></p>
- *
- * <p>The original <code>Calendar</code> API was based on the experience
- * of implementing a only a single subclass,
- * <code>GregorianCalendar</code>. As a result, all of the subclassing
- * kinks had not been worked out. The new subclassing API has been
- * refined based on several implemented subclasses. This includes methods
- * that must be overridden and methods for subclasses to call. Subclasses
- * no longer have direct access to <code>fields</code> and
- * <code>stamp</code>. Instead, they have new API to access
- * these. Subclasses are able to allocate the <code>fields</code> array
- * through a protected framework method; this allows subclasses to
- * specify additional fields. </p>
- *
- * <p>More functionality has been moved into the base class. The base
- * class now contains much of the computational machinery to support the
- * Gregorian calendar. This is based on two things: (1) Many calendars
- * are based on the Gregorian calendar (such as the Buddhist and Japanese
- * imperial calendars). (2) <em>All</em> calendars require basic
- * Gregorian support in order to handle timezone computations. </p>
- *
- * <p>Common computations have been moved into
- * <code>Calendar</code>. Subclasses no longer compute the week related
- * fields and the time related fields. These are commonly handled for all
- * calendars by the base class. </p>
- *
- * <p><b>Subclass computation of time <tt>=&gt;</tt> fields</b>
- *
- * <p>The {@link #ERA}, {@link #YEAR},
- * {@link #EXTENDED_YEAR}, {@link #MONTH},
- * {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields are
- * computed by the subclass, based on the Julian day. All other fields
- * are computed by <code>Calendar</code>.
- *
- * <ul>
- *
- *   <li>Subclasses should implement {@link #handleComputeFields}
- *     to compute the {@link #ERA}, {@link #YEAR},
- *     {@link #EXTENDED_YEAR}, {@link #MONTH},
- *     {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields,
- *     based on the value of the {@link #JULIAN_DAY} field. If there
- *     are calendar-specific fields not defined by <code>Calendar</code>,
- *     they must also be computed. These are the only fields that the
- *     subclass should compute. All other fields are computed by the base
- *     class, so time and week fields behave in a consistent way across
- *     all calendars. The default version of this method in
- *     <code>Calendar</code> implements a proleptic Gregorian
- *     calendar. Within this method, subclasses may call
- *     <code>getGregorianXxx()</code> to obtain the Gregorian calendar
- *     month, day of month, and extended year for the given date.</li>
- *
- * </ul>
- *
- * <p><b>Subclass computation of fields <tt>=&gt;</tt> time</b>
- *
- * <p>The interpretation of most field values is handled entirely by
- * <code>Calendar</code>. <code>Calendar</code> determines which fields
- * are set, which are not, which are set more recently, and so on. In
- * addition, <code>Calendar</code> handles the computation of the time
- * from the time fields and handles the week-related fields. The only
- * thing the subclass must do is determine the extended year, based on
- * the year fields, and then, given an extended year and a month, it must
- * return a Julian day number.
- *
- * <ul>
- *
- *   <li>Subclasses should implement {@link #handleGetExtendedYear}
- *     to return the extended year for this calendar system, based on the
- *     {@link #YEAR}, {@link #EXTENDED_YEAR}, and any fields that
- *     the calendar system uses that are larger than a year, such as
- *     {@link #ERA}.</li>
- *
- *   <li>Subclasses should implement {@link #handleComputeMonthStart}
- *     to return the Julian day number
- *     associated with a month and extended year. This is the Julian day
- *     number of the day before the first day of the month. The month
- *     number is zero-based. This computation should not depend on any
- *     field values.</li>
- *
- * </ul>
- *
- * <p><b>Other methods</b>
- *
- * <ul>
- *
- *   <li>Subclasses should implement {@link #handleGetMonthLength}
- *     to return the number of days in a
- *     given month of a given extended year. The month number, as always,
- *     is zero-based.</li>
- *
- *   <li>Subclasses should implement {@link #handleGetYearLength}
- *     to return the number of days in the given
- *     extended year. This method is used by
- *     <tt>computeWeekFields</tt> to compute the
- *     {@link #WEEK_OF_YEAR} and {@link #YEAR_WOY} fields.</li>
- *
- *   <li>Subclasses should implement {@link #handleGetLimit}
- *     to return the protected values of a field, depending on the value of
- *     <code>limitType</code>. This method only needs to handle the
- *     fields {@link #ERA}, {@link #YEAR}, {@link #MONTH},
- *     {@link #WEEK_OF_YEAR}, {@link #WEEK_OF_MONTH},
- *     {@link #DAY_OF_MONTH}, {@link #DAY_OF_YEAR},
- *     {@link #DAY_OF_WEEK_IN_MONTH}, {@link #YEAR_WOY}, and
- *     {@link #EXTENDED_YEAR}.  Other fields are invariant (with
- *     respect to calendar system) and are handled by the base
- *     class.</li>
- *
- *   <li>Optionally, subclasses may override {@link #validateField}
- *     to check any subclass-specific fields. If the
- *     field's value is out of range, the method should throw an
- *     <code>IllegalArgumentException</code>. The method may call
- *     <code>super.validateField(field)</code> to handle fields in a
- *     generic way, that is, to compare them to the range
- *     <code>getMinimum(field)</code>..<code>getMaximum(field)</code>.</li>
- *
- *   <li>Optionally, subclasses may override
- *     {@link #handleCreateFields} to create an <code>int[]</code>
- *     array large enough to hold the calendar's fields. This is only
- *     necessary if the calendar defines additional fields beyond those
- *     defined by <code>Calendar</code>. The length of the result must be
- *     be between the base and maximum field counts.</li>
- *
- *   <li>Optionally, subclasses may override
- *     {@link #handleGetDateFormat} to create a
- *     <code>DateFormat</code> appropriate to this calendar. This is only
- *     required if a calendar subclass redefines the use of a field (for
- *     example, changes the {@link #ERA} field from a symbolic field
- *     to a numeric one) or defines an additional field.</li>
- *
- *   <li>Optionally, subclasses may override {@link #roll roll} and
- *     {@link #add add} to handle fields that are discontinuous. For
- *     example, in the Hebrew calendar the month &quot;Adar I&quot; only
- *     occurs in leap years; in other years the calendar jumps from
- *     Shevat (month #4) to Adar (month #6). The {@link
- *     HebrewCalendar#add HebrewCalendar.add} and {@link
- *     HebrewCalendar#roll HebrewCalendar.roll} methods take this into
- *     account, so that adding 1 month to Shevat gives the proper result
- *     (Adar) in a non-leap year. The protected utility method {@link
- *     #pinField pinField} is often useful when implementing these two
- *     methods. </li>
- *
- * </ul>
- *
- * <p><big><b>Normalized behavior</b></big>
- *
- * <p>The behavior of certain fields has been made consistent across all
- * calendar systems and implemented in <code>Calendar</code>.
- *
- * <ul>
- *
- *   <li>Time is normalized. Even though some calendar systems transition
- *     between days at sunset or at other times, all ICU4J calendars
- *     transition between days at <em>local zone midnight</em>.  This
- *     allows ICU4J to centralize the time computations in
- *     <code>Calendar</code> and to maintain basic correspondences
- *     between calendar systems. Affected fields: {@link #AM_PM},
- *     {@link #HOUR}, {@link #HOUR_OF_DAY}, {@link #MINUTE},
- *     {@link #SECOND}, {@link #MILLISECOND},
- *     {@link #ZONE_OFFSET}, and {@link #DST_OFFSET}.</li>
- *
- *   <li>DST behavior is normalized. Daylight savings time behavior is
- *     computed the same for all calendar systems, and depends on the
- *     value of several <code>GregorianCalendar</code> fields: the
- *     {@link #YEAR}, {@link #MONTH}, and
- *     {@link #DAY_OF_MONTH}. As a result, <code>Calendar</code>
- *     always computes these fields, even for non-Gregorian calendar
- *     systems. These fields are available to subclasses.</li>
- *
- *   <li>Weeks are normalized. Although locales define the week
- *     differently, in terms of the day on which it starts, and the
- *     designation of week number one of a month or year, they all use a
- *     common mechanism. Furthermore, the day of the week has a simple
- *     and consistent definition throughout history. For example,
- *     although the Gregorian calendar introduced a discontinuity when
- *     first instituted, the day of week was not disrupted. For this
- *     reason, the fields {@link #DAY_OF_WEEK}, <code>WEEK_OF_YEAR,
- *     WEEK_OF_MONTH</code>, {@link #DAY_OF_WEEK_IN_MONTH},
- *     {@link #DOW_LOCAL}, {@link #YEAR_WOY} are all computed in
- *     a consistent way in the base class, based on the
- *     {@link #EXTENDED_YEAR}, {@link #DAY_OF_YEAR},
- *     {@link #MONTH}, and {@link #DAY_OF_MONTH}, which are
- *     computed by the subclass.</li>
- *
- * </ul>
- *
- * <p><big><b>Supported range</b></big>
- *
- * <p>The allowable range of <code>Calendar</code> has been
- * narrowed. <code>GregorianCalendar</code> used to attempt to support
- * the range of dates with millisecond values from
- * <code>Long.MIN_VALUE</code> to <code>Long.MAX_VALUE</code>. This
- * introduced awkward constructions (hacks) which slowed down
- * performance. It also introduced non-uniform behavior at the
- * boundaries. The new <code>Calendar</code> protocol specifies the
- * maximum range of supportable dates as those having Julian day numbers
- * of <code>-0x7F000000</code> to <code>+0x7F000000</code>. This
- * corresponds to years from ~5,000,000 BCE to ~5,000,000 CE. Programmers
- * should use the protected constants in <code>Calendar</code> to
- * specify an extremely early or extremely late date.</p>
- *
- * <p><big><b>General notes</b></big>
- *
- * <ul>
- *
- *   <li>Calendars implementations are <em>proleptic</em>. For example,
- *     even though the Gregorian calendar was not instituted until the
- *     16th century, the <code>GregorianCalendar</code> class supports
- *     dates before the historical onset of the calendar by extending the
- *     calendar system backward in time. Similarly, the
- *     <code>HebrewCalendar</code> extends backward before the start of
- *     its epoch into zero and negative years. Subclasses do not throw
- *     exceptions because a date precedes the historical start of a
- *     calendar system. Instead, they implement
- *     {@link #handleGetLimit} to return appropriate limits on
- *     {@link #YEAR}, {@link #ERA}, etc. fields. Then, if the
- *     calendar is set to not be lenient, out-of-range field values will
- *     trigger an exception.</li>
- *
- *   <li>Calendar system subclasses compute a <em>extended
- *     year</em>. This differs from the {@link #YEAR} field in that
- *     it ranges over all integer values, including zero and negative
- *     values, and it encapsulates the information of the
- *     {@link #YEAR} field and all larger fields.  Thus, for the
- *     Gregorian calendar, the {@link #EXTENDED_YEAR} is computed as
- *     <code>ERA==AD ? YEAR : 1-YEAR</code>. Another example is the Mayan
- *     long count, which has years (<code>KUN</code>) and nested cycles
- *     of years (<code>KATUN</code> and <code>BAKTUN</code>). The Mayan
- *     {@link #EXTENDED_YEAR} is computed as <code>TUN + 20 * (KATUN
- *     + 20 * BAKTUN)</code>. The <code>Calendar</code> base class uses
- *     the {@link #EXTENDED_YEAR} field to compute the week-related
- *     fields.</li>
- *
- * </ul>
- *
- * @see          Date
- * @see          GregorianCalendar
- * @see          TimeZone
- * @see          DateFormat
- * @author Mark Davis, Deborah Goldsmith, Chen-Lieh Huang, Alan Liu, Laura Werner
- * @stable ICU 2.0
- */
-public class Calendar implements Serializable, Cloneable, Comparable<Calendar> {
-    private static final long serialVersionUID = 1L;
-    
-    /**
-     * @internal
-     */
-    public final java.util.Calendar calendar;
-        
-    /**
-     * @internal
-     * @param delegate the Calendar to which to delegate
-     */
-    public Calendar(java.util.Calendar delegate) {
-        this.calendar = delegate;
-    }
-
-    // Data flow in Calendar
-    // ---------------------
-
-    // The current time is represented in two ways by Calendar: as UTC
-    // milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local
-    // fields such as MONTH, HOUR, AM_PM, etc.  It is possible to compute the
-    // millis from the fields, and vice versa.  The data needed to do this
-    // conversion is encapsulated by a TimeZone object owned by the Calendar.
-    // The data provided by the TimeZone object may also be overridden if the
-    // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class
-    // keeps track of what information was most recently set by the caller, and
-    // uses that to compute any other information as needed.
-
-    // If the user sets the fields using set(), the data flow is as follows.
-    // This is implemented by the Calendar subclass's computeTime() method.
-    // During this process, certain fields may be ignored.  The disambiguation
-    // algorithm for resolving which fields to pay attention to is described
-    // above.
-
-    //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
-    //           |
-    //           | Using Calendar-specific algorithm
-    //           V
-    //   local standard millis
-    //           |
-    //           | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET
-    //           V
-    //   UTC millis (in time data member)
-
-    // If the user sets the UTC millis using setTime(), the data flow is as
-    // follows.  This is implemented by the Calendar subclass's computeFields()
-    // method.
-
-    //   UTC millis (in time data member)
-    //           |
-    //           | Using TimeZone getOffset()
-    //           V
-    //   local standard millis
-    //           |
-    //           | Using Calendar-specific algorithm
-    //           V
-    //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
-
-    // In general, a round trip from fields, through local and UTC millis, and
-    // back out to fields is made when necessary.  This is implemented by the
-    // complete() method.  Resolving a partial set of fields into a UTC millis
-    // value allows all remaining fields to be generated from that value.  If
-    // the Calendar is lenient, the fields are also renormalized to standard
-    // ranges when they are regenerated.
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the
-     * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific
-     * value; see subclass documentation.
-     * @see GregorianCalendar#AD
-     * @see GregorianCalendar#BC
-     * @stable ICU 2.0
-     */
-    public final static int ERA = 0;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the
-     * year. This is a calendar-specific value; see subclass documentation.
-     * @stable ICU 2.0
-     */
-    public final static int YEAR = 1;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the
-     * month. This is a calendar-specific value. The first month of the year is
-     * <code>JANUARY</code>; the last depends on the number of months in a year.
-     * @see #JANUARY
-     * @see #FEBRUARY
-     * @see #MARCH
-     * @see #APRIL
-     * @see #MAY
-     * @see #JUNE
-     * @see #JULY
-     * @see #AUGUST
-     * @see #SEPTEMBER
-     * @see #OCTOBER
-     * @see #NOVEMBER
-     * @see #DECEMBER
-     * @see #UNDECIMBER
-     * @stable ICU 2.0
-     */
-    public final static int MONTH = 2;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the
-     * week number within the current year.  The first week of the year, as
-     * defined by {@link #getFirstDayOfWeek()} and
-     * {@link #getMinimalDaysInFirstWeek()}, has value 1.  Subclasses define
-     * the value of {@link #WEEK_OF_YEAR} for days before the first week of
-     * the year.
-     * @see #getFirstDayOfWeek
-     * @see #getMinimalDaysInFirstWeek
-     * @stable ICU 2.0
-     */
-    public final static int WEEK_OF_YEAR = 3;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the
-     * week number within the current month.  The first week of the month, as
-     * defined by {@link #getFirstDayOfWeek()} and
-     * {@link #getMinimalDaysInFirstWeek()}, has value 1.  Subclasses define
-     * the value of {@link #WEEK_OF_MONTH} for days before the first week of
-     * the month.
-     * @see #getFirstDayOfWeek
-     * @see #getMinimalDaysInFirstWeek
-     * @stable ICU 2.0
-     */
-    public final static int WEEK_OF_MONTH = 4;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the
-     * day of the month. This is a synonym for {@link #DAY_OF_MONTH}.
-     * The first day of the month has value 1.
-     * @see #DAY_OF_MONTH
-     * @stable ICU 2.0
-     */
-    public final static int DATE = 5;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the
-     * day of the month. This is a synonym for {@link #DATE}.
-     * The first day of the month has value 1.
-     * @see #DATE
-     * @stable ICU 2.0
-     */
-    public final static int DAY_OF_MONTH = 5;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the day
-     * number within the current year.  The first day of the year has value 1.
-     * @stable ICU 2.0
-     */
-    public final static int DAY_OF_YEAR = 6;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the day
-     * of the week.  This field takes values {@link #SUNDAY},
-     * {@link #MONDAY}, {@link #TUESDAY}, {@link #WEDNESDAY},
-     * {@link #THURSDAY}, {@link #FRIDAY}, and {@link #SATURDAY}.
-     * @see #SUNDAY
-     * @see #MONDAY
-     * @see #TUESDAY
-     * @see #WEDNESDAY
-     * @see #THURSDAY
-     * @see #FRIDAY
-     * @see #SATURDAY
-     * @stable ICU 2.0
-     */
-    public final static int DAY_OF_WEEK = 7;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the
-     * ordinal number of the day of the week within the current month. Together
-     * with the {@link #DAY_OF_WEEK} field, this uniquely specifies a day
-     * within a month.  Unlike {@link #WEEK_OF_MONTH} and
-     * {@link #WEEK_OF_YEAR}, this field's value does <em>not</em> depend on
-     * {@link #getFirstDayOfWeek()} or
-     * {@link #getMinimalDaysInFirstWeek()}.  <code>DAY_OF_MONTH 1</code>
-     * through <code>7</code> always correspond to <code>DAY_OF_WEEK_IN_MONTH
-     * 1</code>; <code>8</code> through <code>15</code> correspond to
-     * <code>DAY_OF_WEEK_IN_MONTH 2</code>, and so on.
-     * <code>DAY_OF_WEEK_IN_MONTH 0</code> indicates the week before
-     * <code>DAY_OF_WEEK_IN_MONTH 1</code>.  Negative values count back from the
-     * end of the month, so the last Sunday of a month is specified as
-     * <code>DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1</code>.  Because
-     * negative values count backward they will usually be aligned differently
-     * within the month than positive values.  For example, if a month has 31
-     * days, <code>DAY_OF_WEEK_IN_MONTH -1</code> will overlap
-     * <code>DAY_OF_WEEK_IN_MONTH 5</code> and the end of <code>4</code>.
-     * @see #DAY_OF_WEEK
-     * @see #WEEK_OF_MONTH
-     * @stable ICU 2.0
-     */
-    public final static int DAY_OF_WEEK_IN_MONTH = 8;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating
-     * whether the <code>HOUR</code> is before or after noon.
-     * E.g., at 10:04:15.250 PM the <code>AM_PM</code> is <code>PM</code>.
-     * @see #AM
-     * @see #PM
-     * @see #HOUR
-     * @stable ICU 2.0
-     */
-    public final static int AM_PM = 9;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the
-     * hour of the morning or afternoon. <code>HOUR</code> is used for the 12-hour
-     * clock.
-     * E.g., at 10:04:15.250 PM the <code>HOUR</code> is 10.
-     * @see #AM_PM
-     * @see #HOUR_OF_DAY
-     * @stable ICU 2.0
-     */
-    public final static int HOUR = 10;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the
-     * hour of the day. <code>HOUR_OF_DAY</code> is used for the 24-hour clock.
-     * E.g., at 10:04:15.250 PM the <code>HOUR_OF_DAY</code> is 22.
-     * @see #HOUR
-     * @stable ICU 2.0
-     */
-    public final static int HOUR_OF_DAY = 11;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the
-     * minute within the hour.
-     * E.g., at 10:04:15.250 PM the <code>MINUTE</code> is 4.
-     * @stable ICU 2.0
-     */
-    public final static int MINUTE = 12;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the
-     * second within the minute.
-     * E.g., at 10:04:15.250 PM the <code>SECOND</code> is 15.
-     * @stable ICU 2.0
-     */
-    public final static int SECOND = 13;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the
-     * millisecond within the second.
-     * E.g., at 10:04:15.250 PM the <code>MILLISECOND</code> is 250.
-     * @stable ICU 2.0
-     */
-    public final static int MILLISECOND = 14;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the
-     * raw offset from GMT in milliseconds.
-     * @stable ICU 2.0
-     */
-    public final static int ZONE_OFFSET = 15;
-
-    /**
-     * Field number for <code>get</code> and <code>set</code> indicating the
-     * daylight savings offset in milliseconds.
-     * @stable ICU 2.0
-     */
-    public final static int DST_OFFSET = 16;
-
-//    /**
-//     * {@icu} Field number for <code>get()</code> and <code>set()</code>
-//     * indicating the extended year corresponding to the
-//     * {@link #WEEK_OF_YEAR} field.  This may be one greater or less
-//     * than the value of {@link #EXTENDED_YEAR}.
-//     * @stable ICU 2.0
-//     */
-//    public static final int YEAR_WOY = 17;
-//
-//    /**
-//     * {@icu} Field number for <code>get()</code> and <code>set()</code>
-//     * indicating the localized day of week.  This will be a value from 1
-//     * to 7 inclusive, with 1 being the localized first day of the week.
-//     * @stable ICU 2.0
-//     */
-//    public static final int DOW_LOCAL = 18;
-//
-//    /**
-//     * {@icu} Field number for <code>get()</code> and <code>set()</code>
-//     * indicating the extended year.  This is a single number designating
-//     * the year of this calendar system, encompassing all supra-year
-//     * fields.  For example, for the Julian calendar system, year numbers
-//     * are positive, with an era of BCE or CE.  An extended year value for
-//     * the Julian calendar system assigns positive values to CE years and
-//     * negative values to BCE years, with 1 BCE being year 0.
-//     * @stable ICU 2.0
-//     */
-//    public static final int EXTENDED_YEAR = 19;
-//
-//    /**
-//     * {@icu} Field number for <code>get()</code> and <code>set()</code>
-//     * indicating the modified Julian day number.  This is different from
-//     * the conventional Julian day number in two regards.  First, it
-//     * demarcates days at local zone midnight, rather than noon GMT.
-//     * Second, it is a local number; that is, it depends on the local time
-//     * zone.  It can be thought of as a single number that encompasses all
-//     * the date-related fields.
-//     * @stable ICU 2.0
-//     */
-//    public static final int JULIAN_DAY = 20;
-//
-//    /**
-//     * {@icu} Field number for <code>get()</code> and <code>set()</code>
-//     * indicating the milliseconds in the day.  This ranges from 0 to
-//     * 23:59:59.999 (regardless of DST).  This field behaves
-//     * <em>exactly</em> like a composite of all time-related fields, not
-//     * including the zone fields.  As such, it also reflects
-//     * discontinuities of those fields on DST transition days.  On a day of
-//     * DST onset, it will jump forward.  On a day of DST cessation, it will
-//     * jump backward.  This reflects the fact that is must be combined with
-//     * the DST_OFFSET field to obtain a unique local time value.
-//     * @stable ICU 2.0
-//     */
-//    public static final int MILLISECONDS_IN_DAY = 21;
-//
-//    /**
-//     * {@icu} Field indicating whether or not the current month is a leap month.
-//     * Should have a value of 0 for non-leap months, and 1 for leap months.
-//     * @draft ICU 4.4
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public static final int IS_LEAP_MONTH = 22;
-
-    /**
-     * Value of the <code>DAY_OF_WEEK</code> field indicating
-     * Sunday.
-     * @stable ICU 2.0
-     */
-    public final static int SUNDAY = 1;
-
-    /**
-     * Value of the <code>DAY_OF_WEEK</code> field indicating
-     * Monday.
-     * @stable ICU 2.0
-     */
-    public final static int MONDAY = 2;
-
-    /**
-     * Value of the <code>DAY_OF_WEEK</code> field indicating
-     * Tuesday.
-     * @stable ICU 2.0
-     */
-    public final static int TUESDAY = 3;
-
-    /**
-     * Value of the <code>DAY_OF_WEEK</code> field indicating
-     * Wednesday.
-     * @stable ICU 2.0
-     */
-    public final static int WEDNESDAY = 4;
-
-    /**
-     * Value of the <code>DAY_OF_WEEK</code> field indicating
-     * Thursday.
-     * @stable ICU 2.0
-     */
-    public final static int THURSDAY = 5;
-
-    /**
-     * Value of the <code>DAY_OF_WEEK</code> field indicating
-     * Friday.
-     * @stable ICU 2.0
-     */
-    public final static int FRIDAY = 6;
-
-    /**
-     * Value of the <code>DAY_OF_WEEK</code> field indicating
-     * Saturday.
-     * @stable ICU 2.0
-     */
-    public final static int SATURDAY = 7;
-
-    /**
-     * Value of the <code>MONTH</code> field indicating the
-     * first month of the year.
-     * @stable ICU 2.0
-     */
-    public final static int JANUARY = 0;
-
-    /**
-     * Value of the <code>MONTH</code> field indicating the
-     * second month of the year.
-     * @stable ICU 2.0
-     */
-    public final static int FEBRUARY = 1;
-
-    /**
-     * Value of the <code>MONTH</code> field indicating the
-     * third month of the year.
-     * @stable ICU 2.0
-     */
-    public final static int MARCH = 2;
-
-    /**
-     * Value of the <code>MONTH</code> field indicating the
-     * fourth month of the year.
-     * @stable ICU 2.0
-     */
-    public final static int APRIL = 3;
-
-    /**
-     * Value of the <code>MONTH</code> field indicating the
-     * fifth month of the year.
-     * @stable ICU 2.0
-     */
-    public final static int MAY = 4;
-
-    /**
-     * Value of the <code>MONTH</code> field indicating the
-     * sixth month of the year.
-     * @stable ICU 2.0
-     */
-    public final static int JUNE = 5;
-
-    /**
-     * Value of the <code>MONTH</code> field indicating the
-     * seventh month of the year.
-     * @stable ICU 2.0
-     */
-    public final static int JULY = 6;
-
-    /**
-     * Value of the <code>MONTH</code> field indicating the
-     * eighth month of the year.
-     * @stable ICU 2.0
-     */
-    public final static int AUGUST = 7;
-
-    /**
-     * Value of the <code>MONTH</code> field indicating the
-     * ninth month of the year.
-     * @stable ICU 2.0
-     */
-    public final static int SEPTEMBER = 8;
-
-    /**
-     * Value of the <code>MONTH</code> field indicating the
-     * tenth month of the year.
-     * @stable ICU 2.0
-     */
-    public final static int OCTOBER = 9;
-
-    /**
-     * Value of the <code>MONTH</code> field indicating the
-     * eleventh month of the year.
-     * @stable ICU 2.0
-     */
-    public final static int NOVEMBER = 10;
-
-    /**
-     * Value of the <code>MONTH</code> field indicating the
-     * twelfth month of the year.
-     * @stable ICU 2.0
-     */
-    public final static int DECEMBER = 11;
-
-    /**
-     * Value of the <code>MONTH</code> field indicating the
-     * thirteenth month of the year. Although {@link GregorianCalendar}
-     * does not use this value, lunar calendars do.
-     * @stable ICU 2.0
-     */
-    public final static int UNDECIMBER = 12;
-
-    /**
-     * Value of the <code>AM_PM</code> field indicating the
-     * period of the day from midnight to just before noon.
-     * @stable ICU 2.0
-     */
-    public final static int AM = 0;
-
-    /**
-     * Value of the <code>AM_PM</code> field indicating the
-     * period of the day from noon to just before midnight.
-     * @stable ICU 2.0
-     */
-    public final static int PM = 1;
-
-    /**
-     * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
-     * weekday.
-     * @see #WEEKEND
-     * @see #WEEKEND_ONSET
-     * @see #WEEKEND_CEASE
-     * @see #getDayOfWeekType
-     * @stable ICU 2.0
-     */
-    public static final int WEEKDAY = 0;
-
-    /**
-     * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
-     * weekend day.
-     * @see #WEEKDAY
-     * @see #WEEKEND_ONSET
-     * @see #WEEKEND_CEASE
-     * @see #getDayOfWeekType
-     * @stable ICU 2.0
-     */
-    public static final int WEEKEND = 1;
-
-    /**
-     * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
-     * day that starts as a weekday and transitions to the weekend.
-     * Call getWeekendTransition() to get the point of transition.
-     * @see #WEEKDAY
-     * @see #WEEKEND
-     * @see #WEEKEND_CEASE
-     * @see #getDayOfWeekType
-     * @stable ICU 2.0
-     */
-    public static final int WEEKEND_ONSET = 2;
-
-    /**
-     * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
-     * day that starts as the weekend and transitions to a weekday.
-     * Call getWeekendTransition() to get the point of transition.
-     * @see #WEEKDAY
-     * @see #WEEKEND
-     * @see #WEEKEND_ONSET
-     * @see #getDayOfWeekType
-     * @stable ICU 2.0
-     */
-    public static final int WEEKEND_CEASE = 3;
-
-    /**
-     * {@icu}Option used by {@link #setRepeatedWallTimeOption(int)} and
-     * {@link #setSkippedWallTimeOption(int)} specifying an ambiguous wall time
-     * to be interpreted as the latest.
-     * @see #setRepeatedWallTimeOption(int)
-     * @see #getRepeatedWallTimeOption()
-     * @see #setSkippedWallTimeOption(int)
-     * @see #getSkippedWallTimeOption()
-     * @draft ICU 49
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final int WALLTIME_LAST = 0;
-
-    /**
-     * {@icu}Option used by {@link #setRepeatedWallTimeOption(int)} and
-     * {@link #setSkippedWallTimeOption(int)} specifying an ambiguous wall time
-     * to be interpreted as the earliest.
-     * @see #setRepeatedWallTimeOption(int)
-     * @see #getRepeatedWallTimeOption()
-     * @see #setSkippedWallTimeOption(int)
-     * @see #getSkippedWallTimeOption()
-     * @draft ICU 49
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final int WALLTIME_FIRST = 1;
-
-    /**
-     * {@icu}Option used by {@link #setSkippedWallTimeOption(int)} specifying an
-     * ambiguous wall time to be interpreted as the next valid wall time.
-     * @see #setSkippedWallTimeOption(int)
-     * @see #getSkippedWallTimeOption()
-     * @draft ICU 49
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final int WALLTIME_NEXT_VALID = 2;
-
-    /**
-     * Constructs a Calendar with the default time zone
-     * and locale.
-     * @see     TimeZone#getDefault
-     * @stable ICU 2.0
-     */
-    protected Calendar()
-    {
-        this(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
-    }
-
-    /**
-     * Constructs a calendar with the specified time zone and locale.
-     * @param zone the time zone to use
-     * @param aLocale the locale for the week data
-     * @stable ICU 2.0
-     */
-    protected Calendar(TimeZone zone, Locale aLocale)
-    {
-        this(zone, ULocale.forLocale(aLocale));
-    }
-
-    /**
-     * Constructs a calendar with the specified time zone and locale.
-     * @param zone the time zone to use
-     * @param locale the ulocale for the week data
-     * @stable ICU 3.2
-     */
-    protected Calendar(TimeZone zone, ULocale locale)
-    {
-        calendar = java.util.Calendar.getInstance(zone.timeZone, locale.toLocale());
-    }
-
-    /**
-     * Returns a calendar using the default time zone and locale.
-     * @return a Calendar.
-     * @stable ICU 2.0
-     */
-    public static synchronized Calendar getInstance()
-    {
-        return new Calendar(java.util.Calendar.getInstance(ULocale.getDefault(Category.FORMAT).toLocale()));
-    }
-
-    /**
-     * Returns a calendar using the specified time zone and default locale.
-     * @param zone the time zone to use
-     * @return a Calendar.
-     * @stable ICU 2.0
-     */
-    public static synchronized Calendar getInstance(TimeZone zone)
-    {
-        return new Calendar(java.util.Calendar.getInstance(zone.timeZone, ULocale.getDefault(Category.FORMAT).toLocale()));
-    }
-
-    /**
-     * Returns a calendar using the default time zone and specified locale.
-     * @param aLocale the locale for the week data
-     * @return a Calendar.
-     * @stable ICU 2.0
-     */
-    public static synchronized Calendar getInstance(Locale aLocale)
-    {
-        return new Calendar(java.util.Calendar.getInstance(aLocale));
-    }
-
-    /**
-     * Returns a calendar using the default time zone and specified locale.
-     * @param locale the ulocale for the week data
-     * @return a Calendar.
-     * @stable ICU 3.2
-     */
-    public static synchronized Calendar getInstance(ULocale locale)
-    {
-        return new Calendar(java.util.Calendar.getInstance(locale.toLocale()));
-    }
-
-    /**
-     * Returns a calendar with the specified time zone and locale.
-     * @param zone the time zone to use
-     * @param aLocale the locale for the week data
-     * @return a Calendar.
-     * @stable ICU 2.0
-     */
-    public static synchronized Calendar getInstance(TimeZone zone,
-                                                    Locale aLocale) {
-        return new Calendar(java.util.Calendar.getInstance(zone.timeZone, aLocale));
-    }
-
-    /**
-     * Returns a calendar with the specified time zone and locale.
-     * @param zone the time zone to use
-     * @param locale the ulocale for the week data
-     * @return a Calendar.
-     * @stable ICU 3.2
-     */
-    public static synchronized Calendar getInstance(TimeZone zone,
-                                                    ULocale locale) {
-        return new Calendar(java.util.Calendar.getInstance(zone.timeZone, locale.toLocale()));
-    }
-
-    /**
-     * Returns the list of locales for which Calendars are installed.
-     * @return the list of locales for which Calendars are installed.
-     * @stable ICU 2.0
-     */
-    public static Locale[] getAvailableLocales()
-    {
-        return java.util.Calendar.getAvailableLocales();
-    }
-
-    /**
-     * {@icu} Returns the list of locales for which Calendars are installed.
-     * @return the list of locales for which Calendars are installed.
-     * @draft ICU 3.2 (retain)
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static ULocale[] getAvailableULocales()
-    {
-        if (availableLocales == null) {
-            synchronized (Calendar.class) {
-                if (availableLocales == null) {
-                    Locale[] locales = Locale.getAvailableLocales();
-                    availableLocales = new ULocale[locales.length];
-                    for (int i = 0; i < locales.length; i++) {
-                        availableLocales[i] = ULocale.forLocale(locales[i]);
-                    }
-                }
-            }
-        }
-        return availableLocales.clone();
-    }
-    private static volatile ULocale[] availableLocales;
-
-//    /**
-//     * {@icu} Given a key and a locale, returns an array of string values in a preferred
-//     * order that would make a difference. These are all and only those values where
-//     * the open (creation) of the service with the locale formed from the input locale
-//     * plus input keyword and that value has different behavior than creation with the
-//     * input locale alone.
-//     * @param key           one of the keys supported by this service.  For now, only
-//     *                      "calendar" is supported.
-//     * @param locale        the locale
-//     * @param commonlyUsed  if set to true it will return only commonly used values
-//     *                      with the given locale in preferred order.  Otherwise,
-//     *                      it will return all the available values for the locale.
-//     * @return an array of string values for the given key and the locale.
-//     * @stable ICU 4.2
-//     */
-//    public static final String[] getKeywordValuesForLocale(String key, ULocale locale,
-//                                                           boolean commonlyUsed) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Returns this Calendar's current time.
-     * @return the current time.
-     * @stable ICU 2.0
-     */
-    public final Date getTime() {
-        return calendar.getTime();
-    }
-
-    /**
-     * Sets this Calendar's current time with the given Date.
-     * 
-     * <p>Note: Calling <code>setTime</code> with
-     * <code>Date(Long.MAX_VALUE)</code> or <code>Date(Long.MIN_VALUE)</code>
-     * may yield incorrect field values from {@link #get(int)}.
-     * @param date the given Date.
-     * @stable ICU 2.0
-     */
-    public final void setTime(Date date) {
-        calendar.setTime(date);
-    }
-
-    /**
-     * Returns this Calendar's current time as a long.
-     * @return the current time as UTC milliseconds from the epoch.
-     * @stable ICU 2.0
-     */
-    public long getTimeInMillis() {
-        return calendar.getTimeInMillis();
-    }
-
-    /**
-     * Sets this Calendar's current time from the given long value.
-     * @param millis the new time in UTC milliseconds from the epoch.
-     * @stable ICU 2.0
-     */
-    public void setTimeInMillis( long millis ) {
-        calendar.setTimeInMillis(millis);
-    }
-
-    /**
-     * Returns the value for a given time field.
-     * @param field the given time field.
-     * @return the value for the given time field.
-     * @stable ICU 2.0
-     */
-    public final int get(int field)
-    {
-        return calendar.get(getJDKField(field));
-    }
-
-    /**
-     * Sets the time field with the given value.
-     * @param field the given time field.
-     * @param value the value to be set for the given time field.
-     * @stable ICU 2.0
-     */
-    public final void set(int field, int value)
-    {
-        calendar.set(getJDKField(field), value);
-    }
-
-    /**
-     * Sets the values for the fields year, month, and date.
-     * Previous values of other fields are retained.  If this is not desired,
-     * call {@link #clear()} first.
-     * @param year the value used to set the YEAR time field.
-     * @param month the value used to set the MONTH time field.
-     * Month value is 0-based. e.g., 0 for January.
-     * @param date the value used to set the DATE time field.
-     * @stable ICU 2.0
-     */
-    public final void set(int year, int month, int date)
-    {
-        calendar.set(getJDKField(YEAR), year);
-        calendar.set(getJDKField(MONTH), month);
-        calendar.set(getJDKField(DATE), date);
-    }
-
-    /**
-     * Sets the values for the fields year, month, date, hour, and minute.
-     * Previous values of other fields are retained.  If this is not desired,
-     * call {@link #clear()} first.
-     * @param year the value used to set the YEAR time field.
-     * @param month the value used to set the MONTH time field.
-     * Month value is 0-based. e.g., 0 for January.
-     * @param date the value used to set the DATE time field.
-     * @param hour the value used to set the HOUR_OF_DAY time field.
-     * @param minute the value used to set the MINUTE time field.
-     * @stable ICU 2.0
-     */
-    public final void set(int year, int month, int date, int hour, int minute)
-    {
-        calendar.set(getJDKField(YEAR), year);
-        calendar.set(getJDKField(MONTH), month);
-        calendar.set(getJDKField(DATE), date);
-        calendar.set(getJDKField(HOUR_OF_DAY), hour);
-        calendar.set(getJDKField(MINUTE), minute);
-    }
-
-    /**
-     * Sets the values for the fields year, month, date, hour, minute, and second.
-     * Previous values of other fields are retained.  If this is not desired,
-     * call {@link #clear} first.
-     * @param year the value used to set the YEAR time field.
-     * @param month the value used to set the MONTH time field.
-     * Month value is 0-based. e.g., 0 for January.
-     * @param date the value used to set the DATE time field.
-     * @param hour the value used to set the HOUR_OF_DAY time field.
-     * @param minute the value used to set the MINUTE time field.
-     * @param second the value used to set the SECOND time field.
-     * @stable ICU 2.0
-     */
-    public final void set(int year, int month, int date, int hour, int minute,
-                          int second)
-    {
-        calendar.set(getJDKField(YEAR), year);
-        calendar.set(getJDKField(MONTH), month);
-        calendar.set(getJDKField(DATE), date);
-        calendar.set(getJDKField(HOUR_OF_DAY), hour);
-        calendar.set(getJDKField(MINUTE), minute);
-        calendar.set(getJDKField(SECOND), second);
-    }
-
-    /**
-     * Clears the values of all the time fields.
-     * @stable ICU 2.0
-     */
-    public final void clear()
-    {
-        calendar.clear();
-    }
-
-    /**
-     * Clears the value in the given time field.
-     * @param field the time field to be cleared.
-     * @stable ICU 2.0
-     */
-    public final void clear(int field)
-    {
-        calendar.clear(getJDKField(field));
-    }
-
-    /**
-     * Determines if the given time field has a value set.
-     * @return true if the given time field has a value set; false otherwise.
-     * @stable ICU 2.0
-     */
-    public final boolean isSet(int field)
-    {
-        return calendar.isSet(getJDKField(field));
-    }
-
-    /**
-     * Compares this calendar to the specified object.
-     * The result is <code>true</code> if and only if the argument is
-     * not <code>null</code> and is a <code>Calendar</code> object that
-     * represents the same calendar as this object.
-     * @param obj the object to compare with.
-     * @return <code>true</code> if the objects are the same;
-     * <code>false</code> otherwise.
-     * @stable ICU 2.0
-     */
-    public boolean equals(Object obj) {
-        try {
-            return calendar.equals(((Calendar)obj).calendar);
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    /**
-     * {@icu} Returns true if the given Calendar object is equivalent to this
-     * one.  An equivalent Calendar will behave exactly as this one
-     * does, but it may be set to a different time.  By contrast, for
-     * the equals() method to return true, the other Calendar must
-     * be set to the same time.
-     *
-     * @param other the Calendar to be compared with this Calendar
-     * @stable ICU 2.4
-     */
-    public boolean isEquivalentTo(Calendar other) {
-        return calendar.getClass() == other.calendar.getClass() &&
-            calendar.isLenient() == other.calendar.isLenient() &&
-            calendar.getFirstDayOfWeek() == other.calendar.getFirstDayOfWeek() &&
-            calendar.getMinimalDaysInFirstWeek() == other.calendar.getMinimalDaysInFirstWeek() &&
-            calendar.getTimeZone().equals(other.calendar.getTimeZone());
-    }
-
-    /**
-     * Returns a hash code for this calendar.
-     * @return a hash code value for this object.
-     * @stable ICU 2.0
-     */
-    public int hashCode() {
-        return calendar.hashCode();
-    }
-
-    /**
-     * Returns the difference in milliseconds between the moment this
-     * calendar is set to and the moment the given calendar or Date object
-     * is set to.
-     */
-    private long compare(Object that) {
-        long thatMs;
-        if (that instanceof Calendar) {
-            thatMs = ((Calendar)that).getTimeInMillis();
-        } else if (that instanceof Date) {
-            thatMs = ((Date)that).getTime();
-        } else {
-            throw new IllegalArgumentException(that + "is not a Calendar or Date");
-        }
-        return getTimeInMillis() - thatMs;
-    }
-
-    /**
-     * Compares the time field records.
-     * Equivalent to comparing result of conversion to UTC.
-     * @param when the Calendar to be compared with this Calendar.
-     * @return true if the current time of this Calendar is before
-     * the time of Calendar when; false otherwise.
-     * @stable ICU 2.0
-     */
-    public boolean before(Object when) {
-        return compare(when) < 0;
-    }
-
-    /**
-     * Compares the time field records.
-     * Equivalent to comparing result of conversion to UTC.
-     * @param when the Calendar to be compared with this Calendar.
-     * @return true if the current time of this Calendar is after
-     * the time of Calendar when; false otherwise.
-     * @stable ICU 2.0
-     */
-    public boolean after(Object when) {
-        return compare(when) > 0;
-    }
-
-    /**
-     * Returns the maximum value that this field could have, given the
-     * current date.  For example, with the Gregorian date February 3, 1997
-     * and the {@link #DAY_OF_MONTH DAY_OF_MONTH} field, the actual maximum
-     * is 28; for February 3, 1996 it is 29.
-     *
-     * <p>The actual maximum computation ignores smaller fields and the
-     * current value of like-sized fields.  For example, the actual maximum
-     * of the DAY_OF_YEAR or MONTH depends only on the year and supra-year
-     * fields.  The actual maximum of the DAY_OF_MONTH depends, in
-     * addition, on the MONTH field and any other fields at that
-     * granularity (such as IS_LEAP_MONTH).  The
-     * DAY_OF_WEEK_IN_MONTH field does not depend on the current
-     * DAY_OF_WEEK; it returns the maximum for any day of week in the
-     * current month.  Likewise for the WEEK_OF_MONTH and WEEK_OF_YEAR
-     * fields.
-     *
-     * @param field the field whose maximum is desired
-     * @return the maximum of the given field for the current date of this calendar
-     * @see #getMaximum
-     * @see #getLeastMaximum
-     * @stable ICU 2.0
-     */
-    public int getActualMaximum(int field) {
-        return calendar.getActualMaximum(getJDKField(field));
-    }
-
-    /**
-     * Returns the minimum value that this field could have, given the current date.
-     * For most fields, this is the same as {@link #getMinimum getMinimum}
-     * and {@link #getGreatestMinimum getGreatestMinimum}.  However, some fields,
-     * especially those related to week number, are more complicated.
-     * <p>
-     * For example, assume {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek}
-     * returns 4 and {@link #getFirstDayOfWeek getFirstDayOfWeek} returns SUNDAY.
-     * If the first day of the month is Sunday, Monday, Tuesday, or Wednesday
-     * there will be four or more days in the first week, so it will be week number 1,
-     * and <code>getActualMinimum(WEEK_OF_MONTH)</code> will return 1.  However,
-     * if the first of the month is a Thursday, Friday, or Saturday, there are
-     * <em>not</em> four days in that week, so it is week number 0, and
-     * <code>getActualMinimum(WEEK_OF_MONTH)</code> will return 0.
-     * <p>
-     * @param field the field whose actual minimum value is desired.
-     * @return the minimum of the given field for the current date of this calendar
-     *
-     * @see #getMinimum
-     * @see #getGreatestMinimum
-     * @stable ICU 2.0
-     */
-    public int getActualMinimum(int field) {
-        return calendar.getActualMinimum(getJDKField(field));
-    }
-
-    /**
-     * Rolls (up/down) a single unit of time on the given field.  If the
-     * field is rolled past its maximum allowable value, it will "wrap" back
-     * to its minimum and continue rolling. For
-     * example, to roll the current date up by one day, you can call:
-     * <p>
-     * <code>roll({@link #DATE}, true)</code>
-     * <p>
-     * When rolling on the {@link #YEAR} field, it will roll the year
-     * value in the range between 1 and the value returned by calling
-     * {@link #getMaximum getMaximum}({@link #YEAR}).
-     * <p>
-     * When rolling on certain fields, the values of other fields may conflict and
-     * need to be changed.  For example, when rolling the <code>MONTH</code> field
-     * for the Gregorian date 1/31/96 upward, the <code>DAY_OF_MONTH</code> field
-     * must be adjusted so that the result is 2/29/96 rather than the invalid
-     * 2/31/96.
-     * <p>
-     * <b>Note:</b> Calling <tt>roll(field, true)</tt> N times is <em>not</em>
-     * necessarily equivalent to calling <tt>roll(field, N)</tt>.  For example,
-     * imagine that you start with the date Gregorian date January 31, 1995.  If you call
-     * <tt>roll(Calendar.MONTH, 2)</tt>, the result will be March 31, 1995.
-     * But if you call <tt>roll(Calendar.MONTH, true)</tt>, the result will be
-     * February 28, 1995.  Calling it one more time will give March 28, 1995, which
-     * is usually not the desired result.
-     * <p>
-     * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather
-     * than attempting to perform arithmetic operations directly on the fields
-     * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
-     * to have fields with non-linear behavior, for example missing months
-     * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
-     * methods will take this into account, while simple arithmetic manipulations
-     * may give invalid results.
-     * <p>
-     * @param field the calendar field to roll.
-     *
-     * @param up    indicates if the value of the specified time field is to be
-     *              rolled up or rolled down. Use <code>true</code> if rolling up,
-     *              <code>false</code> otherwise.
-     *
-     * @exception   IllegalArgumentException if the field is invalid or refers
-     *              to a field that cannot be handled by this method.
-     * @see #roll(int, int)
-     * @see #add
-     * @stable ICU 2.0
-     */
-    public final void roll(int field, boolean up)
-    {
-        calendar.roll(getJDKField(field), up);
-    }
-
-    /**
-     * Rolls (up/down) a specified amount time on the given field.  For
-     * example, to roll the current date up by three days, you can call
-     * <code>roll(Calendar.DATE, 3)</code>.  If the
-     * field is rolled past its maximum allowable value, it will "wrap" back
-     * to its minimum and continue rolling.
-     * For example, calling <code>roll(Calendar.DATE, 10)</code>
-     * on a Gregorian calendar set to 4/25/96 will result in the date 4/5/96.
-     * <p>
-     * When rolling on certain fields, the values of other fields may conflict and
-     * need to be changed.  For example, when rolling the {@link #MONTH MONTH} field
-     * for the Gregorian date 1/31/96 by +1, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field
-     * must be adjusted so that the result is 2/29/96 rather than the invalid
-     * 2/31/96.
-     * <p>
-     * {@icunote} the ICU implementation of this method is able to roll
-     * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET},
-     * and {@link #ZONE_OFFSET ZONE_OFFSET}.  Subclasses may, of course, add support for
-     * additional fields in their overrides of <code>roll</code>.
-     * <p>
-     * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather
-     * than attempting to perform arithmetic operations directly on the fields
-     * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
-     * to have fields with non-linear behavior, for example missing months
-     * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
-     * methods will take this into account, while simple arithmetic manipulations
-     * may give invalid results.
-     * <p>
-     * <b>Subclassing:</b><br>
-     * This implementation of <code>roll</code> assumes that the behavior of the
-     * field is continuous between its minimum and maximum, which are found by
-     * calling {@link #getActualMinimum getActualMinimum} and {@link #getActualMaximum getActualMaximum}.
-     * For most such fields, simple addition, subtraction, and modulus operations
-     * are sufficient to perform the roll.  For week-related fields,
-     * the results of {@link #getFirstDayOfWeek getFirstDayOfWeek} and
-     * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} are also necessary.
-     * Subclasses can override these two methods if their values differ from the defaults.
-     * <p>
-     * Subclasses that have fields for which the assumption of continuity breaks
-     * down must overide <code>roll</code> to handle those fields specially.
-     * For example, in the Hebrew calendar the month "Adar I"
-     * only occurs in leap years; in other years the calendar jumps from
-     * Shevat (month #4) to Adar (month #6).  The
-     * {@link HebrewCalendar#roll HebrewCalendar.roll} method takes this into account,
-     * so that rolling the month of Shevat by one gives the proper result (Adar) in a
-     * non-leap year.
-     * <p>
-     * @param field     the calendar field to roll.
-     * @param amount    the amount by which the field should be rolled.
-     *
-     * @exception   IllegalArgumentException if the field is invalid or refers
-     *              to a field that cannot be handled by this method.
-     * @see #roll(int, boolean)
-     * @see #add
-     * @stable ICU 2.0
-     */
-    public void roll(int field, int amount) {
-        calendar.roll(getJDKField(field), amount);
-    }
-
-    /**
-     * Add a signed amount to a specified field, using this calendar's rules.
-     * For example, to add three days to the current date, you can call
-     * <code>add(Calendar.DATE, 3)</code>.
-     * <p>
-     * When adding to certain fields, the values of other fields may conflict and
-     * need to be changed.  For example, when adding one to the {@link #MONTH MONTH} field
-     * for the Gregorian date 1/31/96, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field
-     * must be adjusted so that the result is 2/29/96 rather than the invalid
-     * 2/31/96.
-     * <p>
-     * {@icunote} The ICU implementation of this method is able to add to
-     * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET},
-     * and {@link #ZONE_OFFSET ZONE_OFFSET}.  Subclasses may, of course, add support for
-     * additional fields in their overrides of <code>add</code>.
-     * <p>
-     * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather
-     * than attempting to perform arithmetic operations directly on the fields
-     * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
-     * to have fields with non-linear behavior, for example missing months
-     * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
-     * methods will take this into account, while simple arithmetic manipulations
-     * may give invalid results.
-     * <p>
-     * <b>Subclassing:</b><br>
-     * This implementation of <code>add</code> assumes that the behavior of the
-     * field is continuous between its minimum and maximum, which are found by
-     * calling {@link #getActualMinimum getActualMinimum} and
-     * {@link #getActualMaximum getActualMaximum}.
-     * For such fields, simple arithmetic operations are sufficient to
-     * perform the add.
-     * <p>
-     * Subclasses that have fields for which this assumption of continuity breaks
-     * down must overide <code>add</code> to handle those fields specially.
-     * For example, in the Hebrew calendar the month "Adar I"
-     * only occurs in leap years; in other years the calendar jumps from
-     * Shevat (month #4) to Adar (month #6).  The
-     * {@link HebrewCalendar#add HebrewCalendar.add} method takes this into account,
-     * so that adding one month
-     * to a date in Shevat gives the proper result (Adar) in a non-leap year.
-     * <p>
-     * @param field     the time field.
-     * @param amount    the amount to add to the field.
-     *
-     * @exception   IllegalArgumentException if the field is invalid or refers
-     *              to a field that cannot be handled by this method.
-     * @see #roll(int, int)
-     * @stable ICU 2.0
-     */
-    public void add(int field, int amount) {
-        calendar.add(getJDKField(field), amount);
-    }
-
-    private static String _getDisplayName(Calendar cal) {
-        String type = cal.getType();
-        if (type.equals("japanese")) {
-            return "Japanese Calendar";
-        } else if (type.equals("buddhist")) {
-            return "Buddhist Calendar";
-        }
-        return "Gregorian Calendar";
-    }
-
-    /**
-     * Returns the name of this calendar in the language of the given locale.
-     * @stable ICU 2.0
-     */
-    public String getDisplayName(Locale loc) {
-        return _getDisplayName(this);
-    }
-
-    /**
-     * Returns the name of this calendar in the language of the given locale.
-     * @stable ICU 3.2
-     */
-    public String getDisplayName(ULocale loc) {
-        return _getDisplayName(this);
-    }
-
-    /**
-     * Compares the times (in millis) represented by two
-     * <code>Calendar</code> objects.
-     *
-     * @param that the <code>Calendar</code> to compare to this.
-     * @return <code>0</code> if the time represented by
-     * this <code>Calendar</code> is equal to the time represented
-     * by that <code>Calendar</code>, a value less than
-     * <code>0</code> if the time represented by this is before
-     * the time represented by that, and a value greater than
-     * <code>0</code> if the time represented by this
-     * is after the time represented by that.
-     * @throws NullPointerException if that
-     * <code>Calendar</code> is null.
-     * @throws IllegalArgumentException if the time of that
-     * <code>Calendar</code> can't be obtained because of invalid
-     * calendar values.
-     * @stable ICU 3.4
-     */
-    public int compareTo(Calendar that) {
-        return calendar.compareTo(that.calendar);
-    }
-
-    //-------------------------------------------------------------------------
-    // Interface for creating custon DateFormats for different types of Calendars
-    //-------------------------------------------------------------------------
-
-    /**
-     * {@icu} Returns a <code>DateFormat</code> appropriate to this calendar.
-     * Subclasses wishing to specialize this behavior should override
-     * {@link #handleGetDateFormat}.
-     * @stable ICU 2.0
-     */
-    public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, Locale loc) {
-        if (dateStyle != DateFormat.NONE) {
-            if (timeStyle == DateFormat.NONE) {
-                return DateFormat.getDateInstance((Calendar)this.clone(), dateStyle, loc);
-            } else {
-                return DateFormat.getDateTimeInstance((Calendar)this.clone(), dateStyle, timeStyle, loc);
-            }
-        } else if (timeStyle != DateFormat.NONE) {
-            return DateFormat.getTimeInstance((Calendar)this.clone(), timeStyle, loc);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * {@icu} Returns a <code>DateFormat</code> appropriate to this calendar.
-     * Subclasses wishing to specialize this behavior should override
-     * {@link #handleGetDateFormat}.
-     * @stable ICU 3.2
-     */
-    public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, ULocale loc) {
-        return getDateTimeFormat(dateStyle, timeStyle, loc.toLocale());
-    }
-
-    //-------------------------------------------------------------------------
-    // Constants
-    //-------------------------------------------------------------------------
-
-    /**
-     * {@icu} Returns the difference between the given time and the time this
-     * calendar object is set to.  If this calendar is set
-     * <em>before</em> the given time, the returned value will be
-     * positive.  If this calendar is set <em>after</em> the given
-     * time, the returned value will be negative.  The
-     * <code>field</code> parameter specifies the units of the return
-     * value.  For example, if <code>fieldDifference(when,
-     * Calendar.MONTH)</code> returns 3, then this calendar is set to
-     * 3 months before <code>when</code>, and possibly some additional
-     * time less than one month.
-     *
-     * <p>As a side effect of this call, this calendar is advanced
-     * toward <code>when</code> by the given amount.  That is, calling
-     * this method has the side effect of calling <code>add(field,
-     * n)</code>, where <code>n</code> is the return value.
-     *
-     * <p>Usage: To use this method, call it first with the largest
-     * field of interest, then with progressively smaller fields.  For
-     * example:
-     *
-     * <pre>
-     * int y = cal.fieldDifference(when, Calendar.YEAR);
-     * int m = cal.fieldDifference(when, Calendar.MONTH);
-     * int d = cal.fieldDifference(when, Calendar.DATE);</pre>
-     *
-     * computes the difference between <code>cal</code> and
-     * <code>when</code> in years, months, and days.
-     *
-     * <p>Note: <code>fieldDifference()</code> is
-     * <em>asymmetrical</em>.  That is, in the following code:
-     *
-     * <pre>
-     * cal.setTime(date1);
-     * int m1 = cal.fieldDifference(date2, Calendar.MONTH);
-     * int d1 = cal.fieldDifference(date2, Calendar.DATE);
-     * cal.setTime(date2);
-     * int m2 = cal.fieldDifference(date1, Calendar.MONTH);
-     * int d2 = cal.fieldDifference(date1, Calendar.DATE);</pre>
-     *
-     * one might expect that <code>m1 == -m2 && d1 == -d2</code>.
-     * However, this is not generally the case, because of
-     * irregularities in the underlying calendar system (e.g., the
-     * Gregorian calendar has a varying number of days per month).
-     *
-     * @param when the date to compare this calendar's time to
-     * @param field the field in which to compute the result
-     * @return the difference, either positive or negative, between
-     * this calendar's time and <code>when</code>, in terms of
-     * <code>field</code>.
-     * @stable ICU 2.0
-     */
-    public int fieldDifference(Date when, int field) {
-        int min = 0;
-        long startMs = getTimeInMillis();
-        long targetMs = when.getTime();
-        // Always add from the start millis.  This accommodates
-        // operations like adding years from February 29, 2000 up to
-        // February 29, 2004.  If 1, 1, 1, 1 is added to the year
-        // field, the DOM gets pinned to 28 and stays there, giving an
-        // incorrect DOM difference of 1.  We have to add 1, reset, 2,
-        // reset, 3, reset, 4.
-        if (startMs < targetMs) {
-            int max = 1;
-            // Find a value that is too large
-            for (;;) {
-                setTimeInMillis(startMs);
-                add(field, max);
-                long ms = getTimeInMillis();
-                if (ms == targetMs) {
-                    return max;
-                } else if (ms > targetMs) {
-                    break;
-                } else {
-                    max <<= 1;
-                    if (max < 0) {
-                        // Field difference too large to fit into int
-                        throw new RuntimeException();
-                    }
-                }
-            }
-            // Do a binary search
-            while ((max - min) > 1) {
-                int t = (min + max) / 2;
-                setTimeInMillis(startMs);
-                add(field, t);
-                long ms = getTimeInMillis();
-                if (ms == targetMs) {
-                    return t;
-                } else if (ms > targetMs) {
-                    max = t;
-                } else {
-                    min = t;
-                }
-            }
-        } else if (startMs > targetMs) {
-            //Eclipse stated the following is "dead code"
-            /*if (false) {
-                // This works, and makes the code smaller, but costs
-                // an extra object creation and an extra couple cycles
-                // of calendar computation.
-                setTimeInMillis(targetMs);
-                min = -fieldDifference(new Date(startMs), field);
-            }*/
-            int max = -1;
-            // Find a value that is too small
-            for (;;) {
-                setTimeInMillis(startMs);
-                add(field, max);
-                long ms = getTimeInMillis();
-                if (ms == targetMs) {
-                    return max;
-                } else if (ms < targetMs) {
-                    break;
-                } else {
-                    max <<= 1;
-                    if (max == 0) {
-                        // Field difference too large to fit into int
-                        throw new RuntimeException();
-                    }
-                }
-            }
-            // Do a binary search
-            while ((min - max) > 1) {
-                int t = (min + max) / 2;
-                setTimeInMillis(startMs);
-                add(field, t);
-                long ms = getTimeInMillis();
-                if (ms == targetMs) {
-                    return t;
-                } else if (ms < targetMs) {
-                    max = t;
-                } else {
-                    min = t;
-                }
-            }
-        }
-        // Set calendar to end point
-        setTimeInMillis(startMs);
-        add(field, min);
-        return min;
-    }
-
-    /**
-     * Sets the time zone with the given time zone value.
-     * @param value the given time zone.
-     * @stable ICU 2.0
-     */
-    public void setTimeZone(TimeZone value)
-    {
-        calendar.setTimeZone(value.timeZone);
-    }
-
-    /**
-     * Returns the time zone.
-     * @return the time zone object associated with this calendar.
-     * @stable ICU 2.0
-     */
-    public TimeZone getTimeZone()
-    {
-        return new TimeZone(calendar.getTimeZone());
-    }
-
-    /**
-     * Specify whether or not date/time interpretation is to be lenient.  With
-     * lenient interpretation, a date such as "February 942, 1996" will be
-     * treated as being equivalent to the 941st day after February 1, 1996.
-     * With strict interpretation, such dates will cause an exception to be
-     * thrown.
-     *
-     * @see DateFormat#setLenient
-     * @stable ICU 2.0
-     */
-    public void setLenient(boolean lenient)
-    {
-        calendar.setLenient(lenient);
-    }
-
-    /**
-     * Tell whether date/time interpretation is to be lenient.
-     * @stable ICU 2.0
-     */
-    public boolean isLenient()
-    {
-        return calendar.isLenient();
-    }
-
-//    /**
-//     * {@icu}Sets the behavior for handling wall time repeating multiple times
-//     * at negative time zone offset transitions. For example, 1:30 AM on
-//     * November 6, 2011 in US Eastern time (America/New_York) occurs twice;
-//     * 1:30 AM EDT, then 1:30 AM EST one hour later. When <code>WALLTIME_FIRST</code>
-//     * is used, the wall time 1:30AM in this example will be interpreted as 1:30 AM EDT
-//     * (first occurrence). When <code>WALLTIME_LAST</code> is used, it will be
-//     * interpreted as 1:30 AM EST (last occurrence). The default value is
-//     * <code>WALLTIME_LAST</code>.
-//     * 
-//     * @param option the behavior for handling repeating wall time, either
-//     * <code>WALLTIME_FIRST</code> or <code>WALLTIME_LAST</code>.
-//     * @throws IllegalArgumentException when <code>option</code> is neither
-//     * <code>WALLTIME_FIRST</code> nor <code>WALLTIME_LAST</code>.
-//     * 
-//     * @see #getRepeatedWallTimeOption()
-//     * @see #WALLTIME_FIRST
-//     * @see #WALLTIME_LAST
-//     * 
-//     * @draft ICU 49
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public void setRepeatedWallTimeOption(int option) {
-//        if (option != WALLTIME_LAST) {
-//            throw new UnsupportedOperationException("The option not supported by com.ibm.icu.base");
-//        }
-//    }
-
-    /**
-     * {@icu}Gets the behavior for handling wall time repeating multiple times
-     * at negative time zone offset transitions.
-     * 
-     * @return the behavior for handling repeating wall time, either
-     * <code>WALLTIME_FIRST</code> or <code>WALLTIME_LAST</code>.
-     * 
-     * @see #setRepeatedWallTimeOption(int)
-     * @see #WALLTIME_FIRST
-     * @see #WALLTIME_LAST
-     * 
-     * @draft ICU 49
-     * @provisional This API might change or be removed in a future release.
-     */
-    public int getRepeatedWallTimeOption() {
-        return WALLTIME_LAST;
-    }
-
-//    /**
-//     * {@icu}Sets the behavior for handling skipped wall time at positive time zone offset
-//     * transitions. For example, 2:30 AM on March 13, 2011 in US Eastern time (America/New_York)
-//     * does not exist because the wall time jump from 1:59 AM EST to 3:00 AM EDT. When
-//     * <code>WALLTIME_FIRST</code> is used, 2:30 AM is interpreted as 30 minutes before 3:00 AM
-//     * EDT, therefore, it will be resolved as 1:30 AM EST. When <code>WALLTIME_LAST</code>
-//     * is used, 2:30 AM is interpreted as 31 minutes after 1:59 AM EST, therefore, it will be
-//     * resolved as 3:30 AM EDT. When <code>WALLTIME_NEXT_VALID</code> is used, 2:30 AM will
-//     * be resolved as next valid wall time, that is 3:00 AM EDT. The default value is
-//     * <code>WALLTIME_LAST</code>.
-//     * <p>
-//     * <b>Note:</b>This option is effective only when this calendar is {@link #isLenient() lenient}.
-//     * When the calendar is strict, such non-existing wall time will cause an exception.
-//     * 
-//     * @param option the behavior for handling skipped wall time at positive time zone
-//     * offset transitions, one of <code>WALLTIME_FIRST</code>, <code>WALLTIME_LAST</code> and
-//     * <code>WALLTIME_NEXT_VALID</code>.
-//     * @throws IllegalArgumentException when <code>option</code> is not any of
-//     * <code>WALLTIME_FIRST</code>, <code>WALLTIME_LAST</code> and <code>WALLTIME_NEXT_VALID</code>.
-//     * 
-//     * @see #getSkippedWallTimeOption()
-//     * @see #WALLTIME_FIRST
-//     * @see #WALLTIME_LAST
-//     * @see #WALLTIME_NEXT_VALID
-//     * 
-//     * @draft ICU 49
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public void setSkippedWallTimeOption(int option) {
-//        if (option != WALLTIME_LAST) {
-//            throw new UnsupportedOperationException("The option not supported by com.ibm.icu.base");
-//        }
-//    }
-
-    /**
-     * {@icu}Gets the behavior for handling skipped wall time at positive time zone offset
-     * transitions.
-     * 
-     * @return the behavior for handling skipped wall time, one of
-     * <code>WALLTIME_FIRST</code>, <code>WALLTIME_LAST</code> and <code>WALLTIME_NEXT_VALID</code>.
-     * 
-     * @see #setSkippedWallTimeOption(int)
-     * @see #WALLTIME_FIRST
-     * @see #WALLTIME_LAST
-     * @see #WALLTIME_NEXT_VALID
-     * 
-     * @draft ICU 49
-     * @provisional This API might change or be removed in a future release.
-     */
-    public int getSkippedWallTimeOption() {
-        return WALLTIME_LAST;
-    }
-
-    /**
-     * Sets what the first day of the week is; e.g., Sunday in US,
-     * Monday in France.
-     * @param value the given first day of the week.
-     * @stable ICU 2.0
-     */
-    public void setFirstDayOfWeek(int value)
-    {
-        calendar.setFirstDayOfWeek(value);
-    }
-
-    /**
-     * Returns what the first day of the week is; e.g., Sunday in US,
-     * Monday in France.
-     * @return the first day of the week.
-     * @stable ICU 2.0
-     */
-    public int getFirstDayOfWeek()
-    {
-        return calendar.getFirstDayOfWeek();
-    }
-
-    /**
-     * Sets what the minimal days required in the first week of the year are.
-     * For example, if the first week is defined as one that contains the first
-     * day of the first month of a year, call the method with value 1. If it
-     * must be a full week, use value 7.
-     * @param value the given minimal days required in the first week
-     * of the year.
-     * @stable ICU 2.0
-     */
-    public void setMinimalDaysInFirstWeek(int value)
-    {
-        calendar.setMinimalDaysInFirstWeek(value);
-    }
-
-    /**
-     * Returns what the minimal days required in the first week of the year are;
-     * e.g., if the first week is defined as one that contains the first day
-     * of the first month of a year, getMinimalDaysInFirstWeek returns 1. If
-     * the minimal days required must be a full week, getMinimalDaysInFirstWeek
-     * returns 7.
-     * @return the minimal days required in the first week of the year.
-     * @stable ICU 2.0
-     */
-    public int getMinimalDaysInFirstWeek()
-    {
-        return calendar.getMinimalDaysInFirstWeek();
-    }
-
-    /**
-     * Returns the minimum value for the given time field.
-     * e.g., for Gregorian DAY_OF_MONTH, 1.
-     * @param field the given time field.
-     * @return the minimum value for the given time field.
-     * @stable ICU 2.0
-     */
-    public final int getMinimum(int field) {
-        return calendar.getMinimum(getJDKField(field));
-    }
-
-    /**
-     * Returns the maximum value for the given time field.
-     * e.g. for Gregorian DAY_OF_MONTH, 31.
-     * @param field the given time field.
-     * @return the maximum value for the given time field.
-     * @stable ICU 2.0
-     */
-    public final int getMaximum(int field) {
-        return calendar.getMaximum(getJDKField(field));
-    }
-
-    /**
-     * Returns the highest minimum value for the given field if varies.
-     * Otherwise same as getMinimum(). For Gregorian, no difference.
-     * @param field the given time field.
-     * @return the highest minimum value for the given time field.
-     * @stable ICU 2.0
-     */
-    public final int getGreatestMinimum(int field) {
-        return calendar.getGreatestMinimum(getJDKField(field));
-    }
-
-    /**
-     * Returns the lowest maximum value for the given field if varies.
-     * Otherwise same as getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28.
-     * @param field the given time field.
-     * @return the lowest maximum value for the given time field.
-     * @stable ICU 2.0
-     */
-    public final int getLeastMaximum(int field) {
-        return calendar.getLeastMaximum(getJDKField(field));
-    }
-
-    //-------------------------------------------------------------------------
-    // Weekend support -- determining which days of the week are the weekend
-    // in a given locale
-    //-------------------------------------------------------------------------
-
-    /**
-     * {@icu} Returns whether the given day of the week is a weekday, a
-     * weekend day, or a day that transitions from one to the other,
-     * in this calendar system.  If a transition occurs at midnight,
-     * then the days before and after the transition will have the
-     * type WEEKDAY or WEEKEND.  If a transition occurs at a time
-     * other than midnight, then the day of the transition will have
-     * the type WEEKEND_ONSET or WEEKEND_CEASE.  In this case, the
-     * method getWeekendTransition() will return the point of
-     * transition.
-     * @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
-     * THURSDAY, FRIDAY, or SATURDAY
-     * @return either WEEKDAY, WEEKEND, WEEKEND_ONSET, or
-     * WEEKEND_CEASE
-     * @exception IllegalArgumentException if dayOfWeek is not
-     * between SUNDAY and SATURDAY, inclusive
-     * @see #WEEKDAY
-     * @see #WEEKEND
-     * @see #WEEKEND_ONSET
-     * @see #WEEKEND_CEASE
-     * @see #getWeekendTransition
-     * @see #isWeekend(Date)
-     * @see #isWeekend()
-     * @stable ICU 2.0
-     */
-    public int getDayOfWeekType(int dayOfWeek) {
-        // weekend always full saturday and sunday with com.ibm.icu.base
-        if (dayOfWeek < SUNDAY || dayOfWeek > 7) {
-            throw new IllegalArgumentException("illegal day of week: " + dayOfWeek);
-        } else if (dayOfWeek == SATURDAY || dayOfWeek == SUNDAY) {
-            return WEEKEND;
-        }
-        return WEEKDAY;}
-
-//    /**
-//     * {@icu} Returns the time during the day at which the weekend begins or end in this
-//     * calendar system.  If getDayOfWeekType(dayOfWeek) == WEEKEND_ONSET return the time
-//     * at which the weekend begins.  If getDayOfWeekType(dayOfWeek) == WEEKEND_CEASE
-//     * return the time at which the weekend ends.  If getDayOfWeekType(dayOfWeek) has some
-//     * other value, then throw an exception.
-//     * @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
-//     * THURSDAY, FRIDAY, or SATURDAY
-//     * @return the milliseconds after midnight at which the
-//     * weekend begins or ends
-//     * @exception IllegalArgumentException if dayOfWeek is not
-//     * WEEKEND_ONSET or WEEKEND_CEASE
-//     * @see #getDayOfWeekType
-//     * @see #isWeekend(Date)
-//     * @see #isWeekend()
-//     * @stable ICU 2.0
-//     */
-//    public int getWeekendTransition(int dayOfWeek) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * {@icu} Returns true if the given date and time is in the weekend in this calendar
-     * system.  Equivalent to calling setTime() followed by isWeekend().  Note: This
-     * method changes the time this calendar is set to.
-     * @param date the date and time
-     * @return true if the given date and time is part of the
-     * weekend
-     * @see #getDayOfWeekType
-     * @see #getWeekendTransition
-     * @see #isWeekend()
-     * @stable ICU 2.0
-     */
-    public boolean isWeekend(Date date) {
-        calendar.setTime(date);
-        return isWeekend();
-    }
-
-    /**
-     * {@icu} Returns true if this Calendar's current date and time is in the weekend in
-     * this calendar system.
-     * @return true if the given date and time is part of the
-     * weekend
-     * @see #getDayOfWeekType
-     * @see #getWeekendTransition
-     * @see #isWeekend(Date)
-     * @stable ICU 2.0
-     */
-    public boolean isWeekend() {
-        // weekend always full saturday and sunday with com.ibm.icu.base
-        int dow = calendar.get(Calendar.DAY_OF_WEEK);
-        if (dow == SATURDAY || dow == SUNDAY) {
-            return true;
-        }
-        return false;
-    }
-
-    //-------------------------------------------------------------------------
-    // End of weekend support
-    //-------------------------------------------------------------------------
-
-    /**
-     * Overrides Cloneable
-     * @stable ICU 2.0
-     */
-    public Object clone()
-    {
-        return new Calendar((java.util.Calendar)calendar.clone());
-    }
-
-    /**
-     * Returns a string representation of this calendar. This method
-     * is intended to be used only for debugging purposes, and the
-     * format of the returned string may vary between implementations.
-     * The returned string may be empty but may not be <code>null</code>.
-     *
-     * @return  a string representation of this calendar.
-     * @stable ICU 2.0
-     */
-    public String toString() {
-        return calendar.toString();
-    }
-
-    /**
-     * {@icu} Returns the number of fields defined by this calendar.  Valid field
-     * arguments to <code>set()</code> and <code>get()</code> are
-     * <code>0..getFieldCount()-1</code>.
-     * @stable ICU 2.0
-     */
-    public final int getFieldCount() {
-        return FIELD_COUNT;
-    }
-
-    private static final int FIELD_COUNT = /* IS_LEAP_MONTH */ DST_OFFSET + 1;
-
-    /**
-     * {@icu} Returns the current Calendar type.  Note, in 3.0 this function will return
-     * 'gregorian' in Calendar to emulate legacy behavior
-     * @return type of calendar (gregorian, etc)
-     * @stable ICU 3.8
-     */
-    public String getType() {
-        // JDK supports Gregorian, Japanese and Buddhist
-        String name = calendar.getClass().getSimpleName().toLowerCase(Locale.US);
-        if (name.contains("japanese")) {
-            return "japanese";
-        } else if (name.contains("buddhist")) {
-            return "buddhist";
-        }
-        return "gregorian";
-    }
-
-    // -------- BEGIN ULocale boilerplate --------
-
-//    /**
-//     * {@icu} Returns the locale that was used to create this object, or null.
-//     * This may may differ from the locale requested at the time of
-//     * this object's creation.  For example, if an object is created
-//     * for locale <tt>en_US_CALIFORNIA</tt>, the actual data may be
-//     * drawn from <tt>en</tt> (the <i>actual</i> locale), and
-//     * <tt>en_US</tt> may be the most specific locale that exists (the
-//     * <i>valid</i> locale).
-//     *
-//     * <p>Note: This method will be implemented in ICU 3.0; ICU 2.8
-//     * contains a partial preview implementation.  The * <i>actual</i>
-//     * locale is returned correctly, but the <i>valid</i> locale is
-//     * not, in most cases.
-//     * @param type type of information requested, either {@link
-//     * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link
-//     * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}.
-//     * @return the information specified by <i>type</i>, or null if
-//     * this object was not constructed from locale data.
-//     * @see com.ibm.icu.util.ULocale
-//     * @see com.ibm.icu.util.ULocale#VALID_LOCALE
-//     * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
-//     * @draft ICU 2.8 (retain)
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public final ULocale getLocale(ULocale.Type type) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    // -------- END ULocale boilerplate --------
-
-
-    private static int getJDKField(int icuField) {
-        switch (icuField) {
-        case ERA:
-            return java.util.Calendar.ERA;
-        case YEAR:
-            return java.util.Calendar.YEAR;
-        case MONTH:
-            return java.util.Calendar.MONTH;
-        case WEEK_OF_YEAR:
-            return java.util.Calendar.WEEK_OF_YEAR;
-        case WEEK_OF_MONTH:
-            return java.util.Calendar.WEEK_OF_MONTH;
-        case DATE:
-            return java.util.Calendar.DATE;
-//        case DAY_OF_MONTH:
-//            return java.util.Calendar.DAY_OF_MONTH;
-        case DAY_OF_YEAR:
-            return java.util.Calendar.DAY_OF_YEAR;
-        case DAY_OF_WEEK:
-            return java.util.Calendar.DAY_OF_WEEK;
-        case DAY_OF_WEEK_IN_MONTH:
-            return java.util.Calendar.DAY_OF_WEEK_IN_MONTH;
-        case AM_PM:
-            return java.util.Calendar.AM_PM;
-        case HOUR:
-            return java.util.Calendar.HOUR;
-        case HOUR_OF_DAY:
-            return java.util.Calendar.HOUR_OF_DAY;
-        case MINUTE:
-            return java.util.Calendar.MINUTE;
-        case SECOND:
-            return java.util.Calendar.SECOND;
-        case MILLISECOND:
-            return java.util.Calendar.MILLISECOND;
-        case ZONE_OFFSET:
-            return java.util.Calendar.ZONE_OFFSET;
-        case DST_OFFSET:
-            return java.util.Calendar.DST_OFFSET;
-
-//        case YEAR_WOY:
-//        case DOW_LOCAL:
-//        case EXTENDED_YEAR:
-//        case JULIAN_DAY:
-//        case MILLISECONDS_IN_DAY:
-//            // Unmappable
-//            throw new UnsupportedOperationException("Calendar field type not supported by com.ibm.icu.base");
-        default:
-            // Illegal
-            throw new ArrayIndexOutOfBoundsException("Specified calendar field is out of range");
-        }
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Currency.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Currency.java
deleted file mode 100644
index 6bfc7ae..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Currency.java
+++ /dev/null
@@ -1,510 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/**
- *******************************************************************************
- * Copyright (C) 2001-2012, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.util;
-
-import java.io.Serializable;
-import java.util.Locale;
-
-import com.ibm.icu.util.ULocale.Category;
-
-/**
- * A class encapsulating a currency, as defined by ISO 4217.  A
- * <tt>Currency</tt> object can be created given a <tt>Locale</tt> or
- * given an ISO 4217 code.  Once created, the <tt>Currency</tt> object
- * can return various data necessary to its proper display:
- *
- * <ul><li>A display symbol, for a specific locale
- * <li>The number of fraction digits to display
- * <li>A rounding increment
- * </ul>
- *
- * The <tt>DecimalFormat</tt> class uses these data to display
- * currencies.
- *
- * <p>Note: This class deliberately resembles
- * <tt>java.util.Currency</tt> but it has a completely independent
- * implementation, and adds features not present in the JDK.
- * @author Alan Liu
- * @stable ICU 2.2
- */
-public class Currency implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * @internal
-     */
-    public final java.util.Currency currency;
-
-    /**
-     * @internal
-     * @param delegate the NumberFormat to which to delegate
-     */
-    public Currency(java.util.Currency delegate) {
-        this.currency = delegate;
-    }
-
-    /**
-     * Selector for getName() indicating a symbolic name for a
-     * currency, such as "$" for USD.
-     * @stable ICU 2.6
-     */
-    public static final int SYMBOL_NAME = 0;
-
-    /**
-     * Selector for ucurr_getName indicating the long name for a
-     * currency, such as "US Dollar" for USD.
-     * @stable ICU 2.6
-     */
-    public static final int LONG_NAME = 1;
-   
-    /**
-     * Selector for getName() indicating the plural long name for a 
-     * currency, such as "US dollar" for USD in "1 US dollar", 
-     * and "US dollars" for USD in "2 US dollars".
-     * @stable ICU 4.2
-     */
-    public static final int PLURAL_LONG_NAME = 2;
-
-    /**
-     * Returns a currency object for the default currency in the given
-     * locale.
-     * @param locale the locale
-     * @return the currency object for this locale
-     * @stable ICU 2.2
-     */
-    public static Currency getInstance(Locale locale) {
-        return new Currency(java.util.Currency.getInstance(locale));
-    }
-
-    /**
-     * Returns a currency object for the default currency in the given
-     * locale.
-     * @stable ICU 3.2
-     */
-    public static Currency getInstance(ULocale locale) {
-        return new Currency(java.util.Currency.getInstance(locale.toLocale()));
-    }
-
-//    /**
-//     * Returns an array of Strings which contain the currency
-//     * identifiers that are valid for the given locale on the 
-//     * given date.  If there are no such identifiers, returns null.
-//     * Returned identifiers are in preference order.
-//     * @param loc the locale for which to retrieve currency codes.
-//     * @param d the date for which to retrieve currency codes for the given locale.
-//     * @return The array of ISO currency codes.
-//     * @stable ICU 4.0
-//     */
-//    public static String[] getAvailableCurrencyCodes(ULocale loc, Date d) {
-//        throw new UnsupportedOperationException("Method not supproted by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Returns the set of available currencies. The returned set of currencies contains all of the
-//     * available currencies, including obsolete ones. The result set can be modified without
-//     * affecting the available currencies in the runtime.
-//     * 
-//     * @return The set of available currencies. The returned set could be empty if there is no
-//     * currency data available.
-//     * 
-//     * @stable ICU 49
-//     */
-//    public static Set<Currency> getAvailableCurrencies() {
-//        throw new UnsupportedOperationException("Method not supproted by com.ibm.icu.base");
-//    }
-
-    /**
-     * Returns a currency object given an ISO 4217 3-letter code.
-     * @param theISOCode the iso code
-     * @return the currency for this iso code
-     * @throws NullPointerException if <code>theISOCode</code> is null.
-     * @throws IllegalArgumentException if <code>theISOCode</code> is not a
-     *         3-letter alpha code.
-     * @stable ICU 2.2
-     */
-    public static Currency getInstance(String theISOCode) {
-        return new Currency(java.util.Currency.getInstance(theISOCode));
-    }
-
-//    /**
-//     * Registers a new currency for the provided locale.  The returned object
-//     * is a key that can be used to unregister this currency object.
-//     * @param currency the currency to register
-//     * @param locale the ulocale under which to register the currency
-//     * @return a registry key that can be used to unregister this currency
-//     * @see #unregister
-//     * @stable ICU 3.2
-//     */
-//    public static Object registerInstance(Currency currency, ULocale locale) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Unregister the currency associated with this key (obtained from
-//     * registerInstance).
-//     * @param registryKey the registry key returned from registerInstance
-//     * @see #registerInstance
-//     * @stable ICU 2.6
-//     */
-//    public static boolean unregister(Object registryKey) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Return an array of the locales for which a currency
-//     * is defined.
-//     * @return an array of the available locales
-//     * @stable ICU 2.2
-//     */
-//    public static Locale[] getAvailableLocales() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Return an array of the ulocales for which a currency
-//     * is defined.
-//     * @return an array of the available ulocales
-//     * @stable ICU 3.2
-//     */
-//    public static ULocale[] getAvailableULocales() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Given a key and a locale, returns an array of values for the key for which data
-//     * exists.  If commonlyUsed is true, these are the values that typically are used
-//     * with this locale, otherwise these are all values for which data exists.  
-//     * This is a common service API.
-//     * <p>
-//     * The only supported key is "currency", other values return an empty array.
-//     * <p>
-//     * Currency information is based on the region of the locale.  If the locale does not
-//     * indicate a region, {@link ULocale#addLikelySubtags(ULocale)} is used to infer a region,
-//     * except for the 'und' locale.
-//     * <p>
-//     * If commonlyUsed is true, only the currencies known to be in use as of the current date
-//     * are returned.  When there are more than one, these are returned in preference order
-//     * (typically, this occurs when a country is transitioning to a new currency, and the
-//     * newer currency is preferred), see 
-//     * <a href="http://unicode.org/reports/tr35/#Supplemental_Currency_Data">Unicode TR#35 Sec. C1</a>.  
-//     * If commonlyUsed is false, all currencies ever used in any locale are returned, in no
-//     * particular order.
-//     * 
-//     * @param key           key whose values to look up.  the only recognized key is "currency"
-//     * @param locale        the locale
-//     * @param commonlyUsed  if true, return only values that are currently used in the locale.
-//     *                      Otherwise returns all values.
-//     * @return an array of values for the given key and the locale.  If there is no data, the
-//     *   array will be empty.
-//     * @stable ICU 4.2
-//     */
-//    public static final String[] getKeywordValuesForLocale(String key, ULocale locale, 
-//            boolean commonlyUsed) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Return a hashcode for this currency.
-     * @stable ICU 2.2
-     */
-    public int hashCode() {
-        return currency.hashCode();
-    }
-
-    /**
-     * Return true if rhs is a Currency instance,
-     * is non-null, and has the same currency code.
-     * @stable ICU 2.2
-     */
-    public boolean equals(Object rhs) {
-        try {
-            return currency.equals(((Currency)rhs).currency);
-        }
-        catch (Exception e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the ISO 4217 3-letter code for this currency object.
-     * @stable ICU 2.2
-     */
-    public String getCurrencyCode() {
-        return currency.getCurrencyCode();
-    }
-
-//    /**
-//     * Returns the ISO 4217 numeric code for this currency object.
-//     * <p>Note: If the ISO 4217 numeric code is not assigned for the currency or
-//     * the currency is unknown, this method returns 0.</p>
-//     * @return The ISO 4217 numeric code of this currency.
-//     * @stable ICU 49
-//     */
-//    public int getNumericCode() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Convenience and compatibility override of getName that
-     * requests the symbol name.
-     * @see #getName
-     * @stable ICU 3.4
-     */
-    public String getSymbol() {
-        return currency.getSymbol(ULocale.getDefault(Category.DISPLAY).toLocale());
-    }
-
-    /**
-     * Convenience and compatibility override of getName that
-     * requests the symbol name.
-     * @param loc the Locale for the symbol
-     * @see #getName
-     * @stable ICU 3.4
-     */
-    public String getSymbol(Locale loc) {
-        return currency.getSymbol(loc);
-    }
-
-    /**
-     * Convenience and compatibility override of getName that
-     * requests the symbol name.
-     * @param uloc the ULocale for the symbol
-     * @see #getName
-     * @stable ICU 3.4
-     */
-    public String getSymbol(ULocale uloc) {
-        return currency.getSymbol(uloc.toLocale());
-    }
-
-//    /**
-//     * Returns the display name for the given currency in the
-//     * given locale.  
-//     * This is a convenient method for 
-//     * getName(ULocale, int, boolean[]); 
-//     * @stable ICU 3.2
-//     */
-//    public String getName(Locale locale,
-//                          int nameStyle,
-//                          boolean[] isChoiceFormat) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Returns the display name for the given currency in the
-//     * given locale.  For example, the display name for the USD
-//     * currency object in the en_US locale is "$".
-//     * @param locale locale in which to display currency
-//     * @param nameStyle selector for which kind of name to return.
-//     *                  The nameStyle should be either SYMBOL_NAME or 
-//     *                  LONG_NAME. Otherwise, throw IllegalArgumentException.
-//     * @param isChoiceFormat fill-in; isChoiceFormat[0] is set to true
-//     * if the returned value is a ChoiceFormat pattern; otherwise it
-//     * is set to false
-//     * @return display string for this currency.  If the resource data
-//     * contains no entry for this currency, then the ISO 4217 code is
-//     * returned.  If isChoiceFormat[0] is true, then the result is a
-//     * ChoiceFormat pattern.  Otherwise it is a static string. <b>Note:</b>
-//     * as of ICU 4.4, choice formats are not used, and the value returned
-//     * in isChoiceFormat is always false.
-//     * <p>
-//     * @throws  IllegalArgumentException  if the nameStyle is not SYMBOL_NAME
-//     *                                    or LONG_NAME.
-//     * @see #getName(ULocale, int, String, boolean[])
-//     * @stable ICU 3.2
-//     */
-//    public String getName(ULocale locale, int nameStyle, boolean[] isChoiceFormat) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Returns the display name for the given currency in the given locale.  
-//     * This is a convenience overload of getName(ULocale, int, String, boolean[]);
-//     * @stable ICU 4.2
-//     */
-//    public String getName(Locale locale, int nameStyle, String pluralCount,
-//            boolean[] isChoiceFormat) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Returns the display name for this currency in the default locale.
-//     * If the resource data for the default locale contains no entry for this currency,
-//     * then the ISO 4217 code is returned.
-//     * <p>
-//     * Note: This method was added for JDK compatibility support and equivalent to
-//     * <code>getName(Locale.getDefault(), LONG_NAME, null)</code>.
-//     * 
-//     * @return The display name of this currency
-//     * @see #getDisplayName(Locale)
-//     * @see #getName(Locale, int, boolean[])
-//     * @stable ICU 49
-//     */
-//    public String getDisplayName() {
-//        //return getName(Locale.getDefault(), LONG_NAME, null);
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Returns the display name for this currency in the given locale.
-//     * If the resource data for the given locale contains no entry for this currency,
-//     * then the ISO 4217 code is returned.
-//     * <p>
-//     * Note: This method was added for JDK compatibility support and equivalent to
-//     * <code>getName(locale, LONG_NAME, null)</code>.
-//     * 
-//     * @param locale locale in which to display currency
-//     * @return The display name of this currency for the specified locale
-//     * @see #getDisplayName(Locale)
-//     * @see #getName(Locale, int, boolean[])
-//     * @stable ICU 49
-//     */
-//    public String getDisplayName(Locale locale) {
-//        //return getName(locale, LONG_NAME, null);
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Returns the display name for the given currency in the
-//     * given locale.  For example, the SYMBOL_NAME for the USD
-//     * currency object in the en_US locale is "$".
-//     * The PLURAL_LONG_NAME for the USD currency object when the currency 
-//     * amount is plural is "US dollars", such as in "3.00 US dollars";
-//     * while the PLURAL_LONG_NAME for the USD currency object when the currency
-//     * amount is singular is "US dollar", such as in "1.00 US dollar".
-//     * @param locale locale in which to display currency
-//     * @param nameStyle selector for which kind of name to return
-//     * @param pluralCount plural count string for this locale
-//     * @param isChoiceFormat fill-in; isChoiceFormat[0] is set to true
-//     * if the returned value is a ChoiceFormat pattern; otherwise it
-//     * is set to false
-//     * @return display string for this currency.  If the resource data
-//     * contains no entry for this currency, then the ISO 4217 code is
-//     * returned.  If isChoiceFormat[0] is true, then the result is a
-//     * ChoiceFormat pattern.  Otherwise it is a static string. <b>Note:</b>
-//     * as of ICU 4.4, choice formats are not used, and the value returned
-//     * in isChoiceFormat is always false.
-//     * @throws  IllegalArgumentException  if the nameStyle is not SYMBOL_NAME,
-//     *                                    LONG_NAME, or PLURAL_LONG_NAME.
-//     * @stable ICU 4.2
-//     */
-//    public String getName(ULocale locale, int nameStyle, String pluralCount,
-//            boolean[] isChoiceFormat) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Attempt to parse the given string as a currency, either as a
-//     * display name in the given locale, or as a 3-letter ISO 4217
-//     * code.  If multiple display names match, then the longest one is
-//     * selected.  If both a display name and a 3-letter ISO code
-//     * match, then the display name is preferred, unless it's length
-//     * is less than 3.
-//     *
-//     * @param locale the locale of the display names to match
-//     * @param text the text to parse
-//     * @param type parse against currency type: LONG_NAME only or not
-//     * @param pos input-output position; on input, the position within
-//     * text to match; must have 0 <= pos.getIndex() < text.length();
-//     * on output, the position after the last matched character. If
-//     * the parse fails, the position in unchanged upon output.
-//     * @return the ISO 4217 code, as a string, of the best match, or
-//     * null if there is no match
-//     *
-//     * @internal
-//     * @deprecated This API is ICU internal only.
-//     */
-//    public static String parse(ULocale locale, String text, int type, ParsePosition pos) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Returns the number of the number of fraction digits that should
-     * be displayed for this currency.
-     * @return a non-negative number of fraction digits to be
-     * displayed
-     * @stable ICU 2.2
-     */
-    public int getDefaultFractionDigits() {
-        return currency.getDefaultFractionDigits();
-    }
-
-//    /**
-//     * Returns the rounding increment for this currency, or 0.0 if no
-//     * rounding is done by this currency.
-//     * @return the non-negative rounding increment, or 0.0 if none
-//     * @stable ICU 2.2
-//     */
-//    public double getRoundingIncrement() {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Returns the ISO 4217 code for this currency.
-     * @stable ICU 2.2
-     */
-    public String toString() {
-        return currency.toString();
-    }
-
-//    /**
-//     * Return the locale that was used to create this object, or null.
-//     * This may may differ from the locale requested at the time of
-//     * this object's creation.  For example, if an object is created
-//     * for locale <tt>en_US_CALIFORNIA</tt>, the actual data may be
-//     * drawn from <tt>en</tt> (the <i>actual</i> locale), and
-//     * <tt>en_US</tt> may be the most specific locale that exists (the
-//     * <i>valid</i> locale).
-//     *
-//     * <p>Note: This method will be obsoleted.  The implementation is
-//     * no longer locale-specific and so there is no longer a valid or
-//     * actual locale associated with the Currency object.  Until
-//     * it is removed, this method will return the root locale.
-//     * @param type type of information requested, either {@link
-//     * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link
-//     * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}.
-//     * @return the information specified by <i>type</i>, or null if
-//     * this object was not constructed from locale data.
-//     * @see com.ibm.icu.util.ULocale
-//     * @see com.ibm.icu.util.ULocale#VALID_LOCALE
-//     * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
-//     * @obsolete ICU 3.2 to be removed
-//     * @deprecated This API is obsolete.
-//     */
-//    public final ULocale getLocale(ULocale.Type type) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Queries if the given ISO 4217 3-letter code is available on the specified date range.
-//     * <p>
-//     * Note: For checking availability of a currency on a specific date, specify the date on both <code>from</code> and
-//     * <code>to</code>. When both <code>from</code> and <code>to</code> are null, this method checks if the specified
-//     * currency is available all time.
-//     * 
-//     * @param code
-//     *            The ISO 4217 3-letter code.
-//     * @param from
-//     *            The lower bound of the date range, inclusive. When <code>from</code> is null, check the availability
-//     *            of the currency any date before <code>to</code>
-//     * @param to
-//     *            The upper bound of the date range, inclusive. When <code>to</code> is null, check the availability of
-//     *            the currency any date after <code>from</code>
-//     * @return true if the given ISO 4217 3-letter code is supported on the specified date range.
-//     * @throws IllegalArgumentException when <code>to</code> is before <code>from</code>.
-//     * 
-//     * @draft ICU 4.6
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public static boolean isAvailable(String code, Date from, Date to) {
-//    	throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-}
-
-//eof
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Freezable.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Freezable.java
deleted file mode 100644
index 0974433..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/Freezable.java
+++ /dev/null
@@ -1,322 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- ******************************************************************************
- * Copyright (C) 2005-2012, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                               *
- ******************************************************************************
-*/
-package com.ibm.icu.util;
-
-/**
- * Provides a flexible mechanism for controlling access, without requiring that
- * a class be immutable. Once frozen, an object can never be unfrozen, so it is
- * thread-safe from that point onward. Once the object has been frozen, 
- * it must guarantee that no changes can be made to it. Any attempt to alter 
- * it must raise an UnsupportedOperationException exception. This means that when 
- * the object returns internal objects, or if anyone has references to those internal
- * objects, that those internal objects must either be immutable, or must also
- * raise exceptions if any attempt to modify them is made. Of course, the object
- * can return clones of internal objects, since those are safe.
- * <h2>Background</h2>
- * <p>
- * There are often times when you need objects to be objects 'safe', so that
- * they can't be modified. Examples are when objects need to be thread-safe, or
- * in writing robust code, or in caches. If you are only creating your own
- * objects, you can guarantee this, of course -- but only if you don't make a
- * mistake. If you have objects handed into you, or are creating objects using
- * others handed into you, it is a different story. It all comes down to whether
- * you want to take the Blanche Dubois approach (&quot;depend on the kindness of
- * strangers&quot;) or the Andy Grove approach (&quot;Only the Paranoid
- * Survive&quot;).
- * </p>
- * <p>
- * For example, suppose we have a simple class:
- * </p>
- * 
- * <pre>
- * public class A {
- *      protected Collection b;
- * 
- *      protected Collection c;
- * 
- *      public Collection get_b() {
- *              return b;
- *      }
- * 
- *      public Collection get_c() {
- *              return c;
- *      }
- * 
- *      public A(Collection new_b, Collection new_c) {
- *              b = new_b;
- *              c = new_c;
- *      }
- * }
- * </pre>
- * 
- * <p>
- * Since the class doesn't have any setters, someone might think that it is
- * immutable. You know where this is leading, of course; this class is unsafe in
- * a number of ways. The following illustrates that.
- * </p>
- * 
- * <pre>
- *  public test1(SupposedlyImmutableClass x, SafeStorage y) {
- *    // unsafe getter
- *    A a = x.getA();
- *    Collection col = a.get_b();
- *    col.add(something); // a has now been changed, and x too
- *
- *    // unsafe constructor
- *    a = new A(col, col);
- *    y.store(a);
- *    col.add(something); // a has now been changed, and y too
- *  }
- * </pre>
- * 
- * <p>
- * There are a few different techniques for having safe classes.
- * </p>
- * <ol>
- * <li>Const objects. In C++, you can declare parameters const.</li>
- * <li>Immutable wrappers. For example, you can put a collection in an
- * immutable wrapper.</li>
- * <li>Always-Immutable objects. Java uses this approach, with a few
- * variations. Examples:
- * <ol>
- * <li>Simple. Once a Color is created (eg from R, G, and B integers) it is
- * immutable.</li>
- * <li>Builder Class. There is a separate 'builder' class. For example,
- * modifiable Strings are created using StringBuffer (which doesn't have the
- * full String API available). Once you want an immutable form, you create one
- * with toString().</li>
- * <li>Primitives. These are always safe, since they are copied on input/output
- * from methods.</li>
- * </ol>
- * </li>
- * <li>Cloning. Where you need an object to be safe, you clone it.</li>
- * </ol>
- * <p>
- * There are advantages and disadvantages of each of these.
- * </p>
- * <ol>
- * <li>Const provides a certain level of protection, but since const can be and
- * is often cast away, it only protects against most inadvertent mistakes. It
- * also offers no threading protection, since anyone who has a pointer to the
- * (unconst) object in another thread can mess you up.</li>
- * <li>Immutable wrappers are safer than const in that the constness can't be
- * cast away. But other than that they have all the same problems: not safe if
- * someone else keeps hold of the original object, or if any of the objects
- * returned by the class are mutable.</li>
- * <li>Always-Immutable Objects are safe, but usage can require excessive
- * object creation.</li>
- * <li>Cloning is only safe if the object truly has a 'safe' clone; defined as
- * one that <i>ensures that no change to the clone affects the original</i>.
- * Unfortunately, many objects don't have a 'safe' clone, and always cloning can
- * require excessive object creation.</li>
- * </ol>
- * <h2>Freezable Model</h2>
- * <p>
- * The <code>Freezable</code> model supplements these choices by giving you
- * the ability to build up an object by calling various methods, then when it is
- * in a final state, you can <i>make</i> it immutable. Once immutable, an
- * object cannot <i>ever </i>be modified, and is completely thread-safe: that
- * is, multiple threads can have references to it without any synchronization.
- * If someone needs a mutable version of an object, they can use
- * <code>cloneAsThawed()</code>, and modify the copy. This provides a simple,
- * effective mechanism for safe classes in circumstances where the alternatives
- * are insufficient or clumsy. (If an object is shared before it is immutable,
- * then it is the responsibility of each thread to mutex its usage (as with
- * other objects).)
- * </p>
- * <p>
- * Here is what needs to be done to implement this interface, depending on the
- * type of the object.
- * </p>
- * <h3><b>Immutable Objects</b></h3>
- * <p>
- * These are the easiest. You just use the interface to reflect that, by adding
- * the following:
- * </p>
- * 
- * <pre>
- *  public class A implements Freezable<A> {
- *   ...
- *   public final boolean isFrozen() {return true;}
- *   public final A freeze() {return this;}
- *   public final A cloneAsThawed() { return this; }
- *   }
- * </pre>
- * 
- * <p>
- * These can be final methods because subclasses of immutable objects must
- * themselves be immutable. (Note: <code>freeze</code> is returning
- * <code>this</code> for chaining.)
- * </p>
- * <h3><b>Mutable Objects</b></h3>
- * <p>
- * Add a protected 'flagging' field:
- * </p>
- * 
- * <pre>
- * protected boolean immutable;
- * </pre>
- * 
- * <p>
- * Add the following methods:
- * </p>
- * 
- * <pre>
- * public final boolean isFrozen() {
- *      return frozen;
- * };
- * 
- * public A freeze() {
- *      frozen = true;
- *      return this;
- * }
- * </pre>
- * 
- * <p>
- * Add a <code>cloneAsThawed()</code> method following the normal pattern for
- * <code>clone()</code>, except that <code>frozen=false</code> in the new
- * clone.
- * </p>
- * <p>
- * Then take the setters (that is, any method that can change the internal state
- * of the object), and add the following as the first statement:
- * </p>
- * 
- * <pre>
- * if (isFrozen()) {
- *      throw new UnsupportedOperationException(&quot;Attempt to modify frozen object&quot;);
- * }
- * </pre>
- * 
- * <h4><b>Subclassing</b></h4>
- * <p>
- * Any subclass of a <code>Freezable</code> will just use its superclass's
- * flagging field. It must override <code>freeze()</code> and
- * <code>cloneAsThawed()</code> to call the superclass, but normally does not
- * override <code>isFrozen()</code>. It must then just pay attention to its
- * own getters, setters and fields.
- * </p>
- * <h4><b>Internal Caches</b></h4>
- * <p>
- * Internal caches are cases where the object is logically unmodified, but
- * internal state of the object changes. For example, there are const C++
- * functions that cast away the const on the &quot;this&quot; pointer in order
- * to modify an object cache. These cases are handled by mutexing the internal
- * cache to ensure thread-safety. For example, suppose that UnicodeSet had an
- * internal marker to the last code point accessed. In this case, the field is
- * not externally visible, so the only thing you need to do is to synchronize
- * the field for thread safety.
- * </p>
- * <h4>Unsafe Internal Access</h4>
- * <p>
- * Internal fields are called <i>safe</i> if they are either
- * <code>frozen</code> or immutable (such as String or primitives). If you've
- * never allowed internal access to these, then you are all done. For example,
- * converting UnicodeSet to be <code>Freezable</code> is just accomplished
- * with the above steps. But remember that you <i><b>have</b></i> allowed
- * access to unsafe internals if you have any code like the following, in a
- * getter, setter, or constructor:
- * </p>
- * 
- * <pre>
- * Collection getStuff() {
- *      return stuff;
- * } // caller could keep reference &amp; modify
- * 
- * void setStuff(Collection x) {
- *      stuff = x;
- * } // caller could keep reference &amp; modify
- * 
- * MyClass(Collection x) {
- *      stuff = x;
- * } // caller could keep reference &amp; modify
- * </pre>
- * 
- * <p>
- * These also illustrated in the code sample in <b>Background</b> above.
- * </p>
- * <p>
- * To deal with unsafe internals, the simplest course of action is to do the
- * work in the <code>freeze()</code> function. Just make all of your internal
- * fields frozen, and set the frozen flag. Any subsequent getter/setter will
- * work properly. Here is an example:
- * </p>
- * 
- * <pre>
- * public A freeze() {
- *      if (!frozen) {
- *              foo.freeze();
- *              frozen = true;
- *      }
- *      return this;
- * }
- * </pre>
- * 
- * <p>
- * If the field is a <code>Collection</code> or <code>Map</code>, then to
- * make it frozen you have two choices. If you have never allowed access to the
- * collection from outside your object, then just wrap it to prevent future
- * modification.
- * </p>
- * 
- * <pre>
- * zone_to_country = Collections.unmodifiableMap(zone_to_country);
- * </pre>
- * 
- * <p>
- * If you have <i>ever</i> allowed access, then do a <code>clone()</code>
- * before wrapping it.
- * </p>
- * 
- * <pre>
- * zone_to_country = Collections.unmodifiableMap(zone_to_country.clone());
- * </pre>
- * 
- * <p>
- * If a collection <i>(or any other container of objects)</i> itself can
- * contain mutable objects, then for a safe clone you need to recurse through it
- * to make the entire collection immutable. The recursing code should pick the
- * most specific collection available, to avoid the necessity of later
- * downcasing.
- * </p>
- * <blockquote>
- * <p>
- * <b>Note: </b>An annoying flaw in Java is that the generic collections, like
- * <code>Map</code> or <code>Set</code>, don't have a <code>clone()</code>
- * operation. When you don't know the type of the collection, the simplest
- * course is to just create a new collection:
- * </p>
- * 
- * <pre>
- * zone_to_country = Collections.unmodifiableMap(new HashMap(zone_to_country));
- * </pre>
- * 
- * </blockquote>
- * @stable ICU 3.8
- */
-public interface Freezable<T> extends Cloneable {
-    /**
-     * Determines whether the object has been frozen or not.
-     * @stable ICU 3.8
-     */
-    public boolean isFrozen();
-
-    /**
-     * Freezes the object.
-     * @return the object itself.
-     * @stable ICU 3.8
-     */
-    public T freeze();
-
-    /**
-     * Provides for the clone operation. Any clone is initially unfrozen.
-     * @stable ICU 3.8
-     */
-    public T cloneAsThawed();
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/IllformedLocaleException.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/IllformedLocaleException.java
deleted file mode 100644
index 1cf8d13..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/IllformedLocaleException.java
+++ /dev/null
@@ -1,75 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- *******************************************************************************
- * Copyright (C) 2009-2011, International Business Machines Corporation and    *
- * others. All Rights Reserved.                                                *
- *******************************************************************************
- */
-package com.ibm.icu.util;
-
-/**
- * Thrown by methods in {@link ULocale} and {@link ULocale.Builder} to
- * indicate that an argument is not a well-formed BCP 47 tag.
- * 
- * @see ULocale
- * @draft ICU 4.2
- * @provisional This API might change or be removed in a future release.
- */
-public class IllformedLocaleException extends RuntimeException {
-
-    private static final long serialVersionUID = 1L;
-
-    private int _errIdx = -1;
-
-    /**
-     * Constructs a new <code>IllformedLocaleException</code> with no
-     * detail message and -1 as the error index.
-     * @draft ICU 4.6
-     * @provisional This API might change or be removed in a future release.
-     */
-    public IllformedLocaleException() {
-        super();
-    }
-
-    /**
-     * Constructs a new <code>IllformedLocaleException</code> with the
-     * given message and -1 as the error index.
-     *
-     * @param message the message
-     * @draft ICU 4.2
-     * @provisional This API might change or be removed in a future release.
-     */
-    public IllformedLocaleException(String message) {
-        super(message);
-    }
-
-    /**
-     * Constructs a new <code>IllformedLocaleException</code> with the
-     * given message and the error index.  The error index is the approximate
-     * offset from the start of the ill-formed value to the point where the
-     * parse first detected an error.  A negative error index value indicates
-     * either the error index is not applicable or unknown.
-     *
-     * @param message the message
-     * @param errorIndex the index
-     * @draft ICU 4.2
-     * @provisional This API might change or be removed in a future release.
-     */
-    public IllformedLocaleException(String message, int errorIndex) {
-        super(message + ((errorIndex < 0) ? "" : " [at index " + errorIndex + "]"));
-        _errIdx = errorIndex;
-    }
-
-    /**
-     * Returns the index where the error was found. A negative value indicates
-     * either the error index is not applicable or unknown.
-     *
-     * @return the error index
-     * @draft ICU 4.2
-     * @provisional This API might change or be removed in a future release.
-     */
-    public int getErrorIndex() {
-        return _errIdx;
-    }
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/TimeZone.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/TimeZone.java
deleted file mode 100644
index 5f2076e..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/TimeZone.java
+++ /dev/null
@@ -1,878 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- * @(#)TimeZone.java    1.51 00/01/19
- *
- * Copyright (C) 1996-2016, International Business Machines
- * Corporation and others.  All Rights Reserved.
- */
-
-package com.ibm.icu.util;
-
-import java.io.Serializable;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Locale;
-import java.util.SimpleTimeZone;
-
-import com.ibm.icu.util.ULocale.Category;
-
-/**
- * {@icuenhanced java.util.TimeZone}.{@icu _usage_}
- *
- * <p><code>TimeZone</code> represents a time zone offset, and also computes daylight
- * savings.
- *
- * <p>Typically, you get a <code>TimeZone</code> using {@link #getDefault()}
- * which creates a <code>TimeZone</code> based on the time zone where the program
- * is running. For example, for a program running in Japan, <code>getDefault</code>
- * creates a <code>TimeZone</code> object based on Japanese Standard Time.
- *
- * <p>You can also get a <code>TimeZone</code> using {@link #getTimeZone(String)}
- * along with a time zone ID. For instance, the time zone ID for the
- * U.S. Pacific Time zone is "America/Los_Angeles". So, you can get a
- * U.S. Pacific Time <code>TimeZone</code> object with:
- *
- * <blockquote>
- * <pre>
- * TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
- * </pre>
- * </blockquote>
- * You can use the {@link #getAvailableIDs()} method to iterate through
- * all the supported time zone IDs. You can then choose a
- * supported ID to get a <code>TimeZone</code>.
- * If the time zone you want is not represented by one of the
- * supported IDs, then you can create a custom time zone ID with
- * the following syntax:
- *
- * <blockquote>
- * <pre>
- * GMT[+|-]hh[[:]mm]
- * </pre>
- * </blockquote>
- *
- * For example, you might specify GMT+14:00 as a custom
- * time zone ID.  The <code>TimeZone</code> that is returned
- * when you specify a custom time zone ID does not include
- * daylight savings time.
- *
- * <p>For compatibility with JDK 1.1.x, some other three-letter time zone IDs
- * (such as "PST", "CTT", "AST") are also supported. However, <strong>their
- * use is deprecated</strong> because the same abbreviation is often used
- * for multiple time zones (for example, "CST" could be U.S. "Central Standard
- * Time" and "China Standard Time"), and the Java platform can then only
- * recognize one of them.
- *
- * <p><strong>Note:</strong> Starting from ICU4J 4.0, you can optionally choose
- * JDK <code>TimeZone</code> as the time zone implementation.  The TimeZone factory
- * method <code>getTimeZone</code> creates an instance of ICU's own <code>TimeZone</code>
- * subclass by default.  If you want to use the JDK implementation always, you can
- * set the default time zone implementation type by the new method
- * <code>setDefaultTimeZoneType</code>.  Alternatively, you can change the initial
- * default implementation type by setting a property below.
- *
- * <blockquote>
- * <pre>
- * #
- * # The default TimeZone implementation type used by the ICU TimeZone
- * # factory method. [ ICU | JDK ]
- * #
- * com.ibm.icu.util.TimeZone.DefaultTimeZoneType = ICU
- * </pre>
- * </blockquote>
- *
- * <p>This property is included in ICUConfig.properties in com.ibm.icu package.  When the
- * <code>TimeZone</code> class is loaded, the initialization code checks if the property
- * <code>com.ibm.icu.util.TimeZone.DefaultTimeZoneType=xxx</code> is defined by the system
- * properties.  If not available, then it loads ICUConfig.properties to get the default
- * time zone implementation type.  The property setting is only used for the initial
- * default value and you can change the default type by calling
- * <code>setDefaultTimeZoneType</code> at runtime.
- *
- * @see          Calendar
- * @see          GregorianCalendar
- * @see          SimpleTimeZone
- * @author       Mark Davis, Deborah Goldsmith, Chen-Lieh Huang, Alan Liu
- * @stable ICU 2.0
- */
-public class TimeZone implements Serializable, Cloneable, Freezable<TimeZone> {
-    private static final long serialVersionUID = 1L;
-    
-    /**
-     * @internal
-     */
-    public final java.util.TimeZone timeZone;
-        
-    /**
-     * @internal
-     * @param delegate the TimeZone to which to delegate
-     */
-    public TimeZone(java.util.TimeZone delegate) {
-        this.timeZone = delegate;
-    }
-
-//    /**
-//     * {@icu} A logger for TimeZone. Will be null if logging is not on by way of system
-//     * property: "icu4j.debug.logging"
-//     * @draft ICU 4.4
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public static ICULogger TimeZoneLogger = ICULogger.getICULogger(TimeZone.class.getName());
-
-    /**
-     * Default constructor.  (For invocation by subclass constructors,
-     * typically implicit.)
-     * @stable ICU 2.8
-     */
-    public TimeZone() {
-        this.timeZone = java.util.TimeZone.getDefault();
-    }
-
-    /**
-     * {@icu} A time zone implementation type indicating ICU's own TimeZone used by
-     * <code>getTimeZone</code>, <code>setDefaultTimeZoneType</code>
-     * and <code>getDefaultTimeZoneType</code>.
-     * @stable ICU 4.0
-     */
-    public static final int TIMEZONE_ICU = 0;
-    /**
-     * {@icu} A time zone implementation type indicating JDK TimeZone used by
-     * <code>getTimeZone</code>, <code>setDefaultTimeZoneType</code>
-     * and <code>getDefaultTimeZoneType</code>.
-     * @stable ICU 4.0
-     */
-    public static final int TIMEZONE_JDK = 1;
-
-    /**
-     * A style specifier for <code>getDisplayName()</code> indicating
-     * a short name, such as "PST."
-     * @see #LONG
-     * @stable ICU 2.0
-     */
-    public static final int SHORT = 0;
-
-    /**
-     * A style specifier for <code>getDisplayName()</code> indicating
-     * a long name, such as "Pacific Standard Time."
-     * @see #SHORT
-     * @stable ICU 2.0
-     */
-    public static final int LONG  = 1;
-
-//    /**
-//     * {@icu} A style specifier for <code>getDisplayName()</code> indicating
-//     * a short generic name, such as "PT."
-//     * @see #LONG_GENERIC
-//     * @draft ICU 4.4
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public static final int SHORT_GENERIC = 2;
-//
-//    /**
-//     * {@icu} A style specifier for <code>getDisplayName()</code> indicating
-//     * a long generic name, such as "Pacific Time."
-//     * @see #SHORT_GENERIC
-//     * @draft ICU 4.4
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public static final int LONG_GENERIC = 3;
-//
-//    /**
-//     * {@icu} A style specifier for <code>getDisplayName()</code> indicating
-//     * a short name derived from the timezone's offset, such as "-0800."
-//     * @see #LONG_GMT
-//     * @draft ICU 4.4
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public static final int SHORT_GMT = 4;
-//
-//    /**
-//     * {@icu} A style specifier for <code>getDisplayName()</code> indicating
-//     * a long name derived from the timezone's offset, such as "GMT-08:00."
-//     * @see #SHORT_GMT
-//     * @draft ICU 4.4
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public static final int LONG_GMT = 5;
-//
-//    /**
-//     * {@icu} A style specifier for <code>getDisplayName()</code> indicating
-//     * a short name derived from the timezone's short standard or daylight
-//     * timezone name ignoring commonlyUsed, such as "PDT."
-//     * @draft ICU 4.4
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//
-//    public static final int SHORT_COMMONLY_USED = 6;
-//
-//    /**
-//     * {@icu} A style specifier for <code>getDisplayName()</code> indicating
-//     * a long name derived from the timezone's fallback name, such as
-//     * "United States (Los Angeles)."
-//     * @draft ICU 4.4
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public static final int GENERIC_LOCATION = 7;
-//
-//    /**
-//     * Gets the time zone offset, for current date, modified in case of
-//     * daylight savings. This is the offset to add *to* UTC to get local time.
-//     * @param era the era of the given date.
-//     * @param year the year in the given date.
-//     * @param month the month in the given date.
-//     * Month is 0-based. e.g., 0 for January.
-//     * @param day the day-in-month of the given date.
-//     * @param dayOfWeek the day-of-week of the given date.
-//     * @param milliseconds the millis in day in <em>standard</em> local time.
-//     * @return the offset to add *to* GMT to get local time.
-//     * @stable ICU 2.0
-//     */
-    
-//    /**
-//     * {@icu} System time zone type constants used by filtering zones in
-//     * {@link TimeZone#getAvailableIDs(SystemTimeZoneType, String, Integer)}
-//     *
-//     * @draft ICU 4.8
-//     * @provisional This API might change or be removed in a future release.
-//     */
-//    public enum SystemTimeZoneType {
-//        /**
-//         * Any system zones.
-//         * @draft ICU 4.8
-//         * @provisional This API might change or be removed in a future release.
-//         */
-//        ANY,
-//
-//        /**
-//         * Canonical system zones.
-//         * @draft ICU 4.8
-//         * @provisional This API might change or be removed in a future release.
-//         */
-//        CANONICAL,
-//
-//        /**
-//         * Canonical system zones associated with actual locations.
-//         * @draft ICU 4.8
-//         * @provisional This API might change or be removed in a future release.
-//         */
-//        CANONICAL_LOCATION,
-//    }
-    
-    public int getOffset(int era, int year, int month, int day,
-                                  int dayOfWeek, int milliseconds) {
-        return timeZone.getOffset(era, year, month, day, dayOfWeek, milliseconds);
-    }
-
-
-    /**
-     * Returns the offset of this time zone from UTC at the specified
-     * date. If Daylight Saving Time is in effect at the specified
-     * date, the offset value is adjusted with the amount of daylight
-     * saving.
-     *
-     * @param date the date represented in milliseconds since January 1, 1970 00:00:00 GMT
-     * @return the amount of time in milliseconds to add to UTC to get local time.
-     *
-     * @see Calendar#ZONE_OFFSET
-     * @see Calendar#DST_OFFSET
-     * @see #getOffset(long, boolean, int[])
-     * @stable ICU 2.8
-     */
-    public int getOffset(long date) {
-        return timeZone.getOffset(date);
-    }
-
-//    /**
-//     * Returns the time zone raw and GMT offset for the given moment
-//     * in time.  Upon return, local-millis = GMT-millis + rawOffset +
-//     * dstOffset.  All computations are performed in the proleptic
-//     * Gregorian calendar.  The default implementation in the TimeZone
-//     * class delegates to the 8-argument getOffset().
-//     *
-//     * @param date moment in time for which to return offsets, in
-//     * units of milliseconds from January 1, 1970 0:00 GMT, either GMT
-//     * time or local wall time, depending on `local'.
-//     * @param local if true, `date' is local wall time; otherwise it
-//     * is in GMT time.
-//     * @param offsets output parameter to receive the raw offset, that
-//     * is, the offset not including DST adjustments, in offsets[0],
-//     * and the DST offset, that is, the offset to be added to
-//     * `rawOffset' to obtain the total offset between local and GMT
-//     * time, in offsets[1]. If DST is not in effect, the DST offset is
-//     * zero; otherwise it is a positive value, typically one hour.
-//     *
-//     * @stable ICU 2.8
-//     */
-//    public void getOffset(long date, boolean local, int[] offsets) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Sets the base time zone offset to GMT.
-     * This is the offset to add *to* UTC to get local time.
-     * @param offsetMillis the given base time zone offset to GMT.
-     * @stable ICU 2.0
-     */
-    public void setRawOffset(int offsetMillis) {
-        if (isFrozen) {
-            throw new UnsupportedOperationException("Attempt to modify a frozen TimeZone instance.");
-        }
-        timeZone.setRawOffset(offsetMillis);
-    }
-
-    /**
-     * Gets unmodified offset, NOT modified in case of daylight savings.
-     * This is the offset to add *to* UTC to get local time.
-     * @return the unmodified offset to add *to* UTC to get local time.
-     * @stable ICU 2.0
-     */
-    public int getRawOffset() {
-        return timeZone.getRawOffset();
-    }
-
-    /**
-     * Gets the ID of this time zone.
-     * @return the ID of this time zone.
-     * @stable ICU 2.0
-     */
-    public String getID() {
-        return timeZone.getID();
-    }
-
-    /**
-     * Sets the time zone ID. This does not change any other data in
-     * the time zone object.
-     * @param ID the new time zone ID.
-     * @stable ICU 2.0
-     */
-    public void setID(String ID) {
-        if (isFrozen) {
-            throw new UnsupportedOperationException("Attempt to modify a frozen TimeZone instance.");
-        }
-        timeZone.setID(ID);
-    }
-
-    /**
-     * Returns a name of this time zone suitable for presentation to the user
-     * in the default locale.
-     * This method returns the long generic name.
-     * If the display name is not available for the locale,
-     * a fallback based on the country, city, or time zone id will be used.
-     * @return the human-readable name of this time zone in the default locale.
-     * @stable ICU 2.0
-     */
-    public final String getDisplayName() {
-        return timeZone.getDisplayName(ULocale.getDefault(Category.DISPLAY).toLocale());
-    }
-
-    /**
-     * Returns a name of this time zone suitable for presentation to the user
-     * in the specified locale.
-     * This method returns the long generic name.
-     * If the display name is not available for the locale,
-     * a fallback based on the country, city, or time zone id will be used.
-     * @param locale the locale in which to supply the display name.
-     * @return the human-readable name of this time zone in the given locale
-     * or in the default locale if the given locale is not recognized.
-     * @stable ICU 2.0
-     */
-    public final String getDisplayName(Locale locale) {
-        return timeZone.getDisplayName(locale);
-    }
-
-    /**
-     * Returns a name of this time zone suitable for presentation to the user
-     * in the specified locale.
-     * This method returns the long name, not including daylight savings.
-     * If the display name is not available for the locale,
-     * a fallback based on the country, city, or time zone id will be used.
-     * @param locale the ulocale in which to supply the display name.
-     * @return the human-readable name of this time zone in the given locale
-     * or in the default ulocale if the given ulocale is not recognized.
-     * @stable ICU 3.2
-     */
-    public final String getDisplayName(ULocale locale) {
-        return timeZone.getDisplayName(locale.toLocale());
-    }
-
-    /**
-     * Returns a name of this time zone suitable for presentation to the user
-     * in the default locale.
-     * If the display name is not available for the locale,
-     * then this method returns a string in the format
-     * <code>GMT[+-]hh:mm</code>.
-     * @param daylight if true, return the daylight savings name.
-     * @param style the output style of the display name.  Valid styles are
-     * <code>SHORT</code>, <code>LONG</code>, <code>SHORT_GENERIC</code>,
-     * <code>LONG_GENERIC</code>, <code>SHORT_GMT</code>, <code>LONG_GMT</code>,
-     * <code>SHORT_COMMONLY_USED</code> or <code>GENERIC_LOCATION</code>.
-     * @return the human-readable name of this time zone in the default locale.
-     * @stable ICU 2.0
-     */
-    public final String getDisplayName(boolean daylight, int style) {
-        return getDisplayName(daylight, style, ULocale.getDefault(Category.DISPLAY));
-    }
-
-    /**
-     * Returns a name of this time zone suitable for presentation to the user
-     * in the specified locale.
-     * If the display name is not available for the locale,
-     * then this method returns a string in the format
-     * <code>GMT[+-]hh:mm</code>.
-     * @param daylight if true, return the daylight savings name.
-     * @param style the output style of the display name.  Valid styles are
-     * <code>SHORT</code>, <code>LONG</code>, <code>SHORT_GENERIC</code>,
-     * <code>LONG_GENERIC</code>, <code>SHORT_GMT</code>, <code>LONG_GMT</code>,
-     * <code>SHORT_COMMONLY_USED</code> or <code>GENERIC_LOCATION</code>.
-     * @param locale the locale in which to supply the display name.
-     * @return the human-readable name of this time zone in the given locale
-     * or in the default locale if the given locale is not recognized.
-     * @exception IllegalArgumentException style is invalid.
-     * @stable ICU 2.0
-     */
-    public String getDisplayName(boolean daylight, int style, Locale locale) {
-        return getDisplayName(daylight, style, ULocale.forLocale(locale));
-    }
-
-    /**
-     * Returns a name of this time zone suitable for presentation to the user
-     * in the specified locale.
-     * If the display name is not available for the locale,
-     * then this method returns a string in the format
-     * <code>GMT[+-]hh:mm</code>.
-     * @param daylight if true, return the daylight savings name.
-     * @param style the output style of the display name.  Valid styles are
-     * <code>SHORT</code>, <code>LONG</code>, <code>SHORT_GENERIC</code>,
-     * <code>LONG_GENERIC</code>, <code>SHORT_GMT</code>, <code>LONG_GMT</code>,
-     * <code>SHORT_COMMONLY_USED</code> or <code>GENERIC_LOCATION</code>.
-     * @param locale the locale in which to supply the display name.
-     * @return the human-readable name of this time zone in the given locale
-     * or in the default locale if the given locale is not recognized.
-     * @exception IllegalArgumentException style is invalid.
-     * @stable ICU 3.2
-     */
-    public String getDisplayName(boolean daylight, int style, ULocale locale) {
-        if (style == SHORT) {
-            return timeZone.getDisplayName(daylight, java.util.TimeZone.SHORT, locale.toLocale());
-        } else if (style == LONG) {
-            return timeZone.getDisplayName(daylight, java.util.TimeZone.LONG, locale.toLocale());
-        } else {
-            throw new UnsupportedOperationException("Specified time zone format style is not supported by com.ibm.icu.base");
-        }
-    }
-
-    /**
-     * Returns the amount of time to be added to local standard time
-     * to get local wall clock time.
-     * <p>
-     * The default implementation always returns 3600000 milliseconds
-     * (i.e., one hour) if this time zone observes Daylight Saving
-     * Time. Otherwise, 0 (zero) is returned.
-     * <p>
-     * If an underlying TimeZone implementation subclass supports
-     * historical Daylight Saving Time changes, this method returns
-     * the known latest daylight saving value.
-     *
-     * @return the amount of saving time in milliseconds
-     * @stable ICU 2.8
-     */
-    public int getDSTSavings() {
-        return timeZone.getDSTSavings();
-    }
-
-    /**
-     * Queries if this time zone uses daylight savings time.
-     * @return true if this time zone uses daylight savings time,
-     * false, otherwise.
-     * @stable ICU 2.0
-     */
-    public boolean useDaylightTime() {
-        return timeZone.useDaylightTime();
-    }
-
-//    /**
-//     * Queries if this time zone is in daylight saving time or will observe
-//     * daylight saving time at any future time.
-//     * <p>The default implementation in this class returns <code>true</code> if {@link #useDaylightTime()}
-//     * or {@link #inDaylightTime(Date) inDaylightTime(new Date())} returns <code>true</code>.
-//     * <p>
-//     * <strong>Note:</strong> This method was added for JDK compatibility support.
-//     * The JDK's <code>useDaylightTime()</code> only checks the last known rule(s), therefore
-//     * it may return false even the zone observes daylight saving time currently. JDK added
-//     * <code>observesDaylightTime()</code> to resolve the issue. In ICU, {@link #useDaylightTime()}
-//     * works differently. The ICU implementation checks if the zone uses daylight saving time
-//     * in the current calendar year. Therefore, it will never return <code>false</code> if
-//     * daylight saving time is currently used.
-//     * <p>
-//     * ICU's TimeZone subclass implementations override this method to support the same behavior
-//     * with JDK's <code>observesDaylightSavingTime()</code>. Unlike {@link #useDaylightTime()},
-//     * the implementation does not take past daylight saving time into account, so
-//     * that this method may return <code>false</code> even when {@link #useDaylightTime()} returns
-//     * <code>true</code>.
-//     * 
-//     * @return <code>true</code> if this time zone is in daylight saving time or will observe
-//     * daylight saving time at any future time.
-//     * @see #useDaylightTime
-//     * @stable ICU 49
-//     */
-//    public boolean observesDaylightTime() {
-//        throw new UnsupportedOperationException("Method not supproted by com.ibm.icu.base");
-//    }
-
-    /**
-     * Queries if the given date is in daylight savings time in
-     * this time zone.
-     * @param date the given Date.
-     * @return true if the given date is in daylight savings time,
-     * false, otherwise.
-     * @stable ICU 2.0
-     */
-    public boolean inDaylightTime(Date date) {
-        return timeZone.inDaylightTime(date);
-    }
-
-    /**
-     * Gets the <code>TimeZone</code> for the given ID.
-     *
-     * @param ID the ID for a <code>TimeZone</code>, such as "America/Los_Angeles",
-     * or a custom ID such as "GMT-8:00". Note that the support of abbreviations,
-     * such as "PST", is for JDK 1.1.x compatibility only and full names should be used.
-     *
-     * @return the specified <code>TimeZone</code>, or the GMT zone if the given ID
-     * cannot be understood.
-     * @stable ICU 2.0
-     */
-    public static synchronized TimeZone getTimeZone(String ID) {
-        return new TimeZone(java.util.TimeZone.getTimeZone(ID));
-    }
-
-    /**
-     * Gets the <code>TimeZone</code> for the given ID. The instance of <code>TimeZone</code>
-     * returned by this method is immutable. Any methods mutate the instance({@link #setID(String)},
-     * {@link #setRawOffset(int)}) will throw <code>UnsupportedOperationException</code> upon its
-     * invocation.
-     *
-     * @param ID the ID for a <code>TimeZone</code>, such as "America/Los_Angeles",
-     * or a custom ID such as "GMT-8:00". Note that the support of abbreviations,
-     * such as "PST", is for JDK 1.1.x compatibility only and full names should be used.
-     *
-     * @return the specified <code>TimeZone</code>, or the UNKNOWN_ZONE
-     * if the given ID cannot be understood.
-     * @see #UNKNOWN_ZONE
-     * @draft ICU 49
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static TimeZone getFrozenTimeZone(String ID) {
-        return getTimeZone(ID).freeze();
-    }
-
-    /**
-     * Gets the <code>TimeZone</code> for the given ID and the timezone type.
-     * @param ID the ID for a <code>TimeZone</code>, such as "America/Los_Angeles", or a
-     * custom ID such as "GMT-8:00". Note that the support of abbreviations, such as
-     * "PST", is for JDK 1.1.x compatibility only and full names should be used.
-     * @param type Time zone type, either <code>TIMEZONE_ICU</code> or
-     * <code>TIMEZONE_JDK</code>.
-     * @return the specified <code>TimeZone</code>, or the GMT zone if the given ID
-     * cannot be understood.
-     * @stable ICU 4.0
-     */
-    public static synchronized TimeZone getTimeZone(String ID, int type) {
-        if (type == TIMEZONE_JDK) {
-            return new TimeZone(java.util.TimeZone.getTimeZone(ID));
-        }
-        throw new UnsupportedOperationException("TIMEZONE_ICU not supported by com.ibm.icu.base");
-    }
-
-    /**
-     * Sets the default time zone type used by <code>getTimeZone</code>.
-     * @param type time zone type, either <code>TIMEZONE_ICU</code> or
-     * <code>TIMEZONE_JDK</code>.
-     * @stable ICU 4.0
-     */
-    public static synchronized void setDefaultTimeZoneType(int type) {
-        if (type != TIMEZONE_JDK) {
-            throw new UnsupportedOperationException("TimeZone type other than TIMEZONE_JDK is not supported by com.ibm.icu.base");
-        }
-    }
-
-    /**
-     * {@icu} Returns the default time zone type currently used.
-     * @return The default time zone type, either <code>TIMEZONE_ICU</code> or
-     * <code>TIMEZONE_JDK</code>.
-     * @stable ICU 4.0
-     */
-    public static int getDefaultTimeZoneType() {
-        return TIMEZONE_JDK;
-    }
-
-//    /** 
-//     * {@icu} Returns a set of time zone ID strings with the given filter conditions. 
-//     * <p><b>Note:</b>A <code>Set</code> returned by this method is
-//     * immutable.
-//     * @param zoneType      The system time zone type.
-//     * @param region        The ISO 3166 two-letter country code or UN M.49 three-digit area code. 
-//     *                      When null, no filtering done by region. 
-//     * @param rawOffset     An offset from GMT in milliseconds, ignoring the effect of daylight savings 
-//     *                      time, if any. When null, no filtering done by zone offset. 
-//     * @return an immutable set of system time zone IDs.
-//     * @see SystemTimeZoneType
-//     * 
-//     * @draft ICU 4.8
-//     * @provisional This API might change or be removed in a future release.
-//     */ 
-//    public static Set<String> getAvailableIDs(SystemTimeZoneType zoneType,
-//            String region, Integer rawOffset) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-    
-    /**
-     * Return a new String array containing all system TimeZone IDs
-     * with the given raw offset from GMT.  These IDs may be passed to
-     * <code>get()</code> to construct the corresponding TimeZone
-     * object.
-     * @param rawOffset the offset in milliseconds from GMT
-     * @return an array of IDs for system TimeZones with the given
-     * raw offset.  If there are none, return a zero-length array.
-     * @stable ICU 2.0
-     */
-    public static String[] getAvailableIDs(int rawOffset) {
-        return java.util.TimeZone.getAvailableIDs(rawOffset);
-
-    }
-
-
-//    /**
-//     * Return a new String array containing all system TimeZone IDs
-//     * associated with the given country.  These IDs may be passed to
-//     * <code>get()</code> to construct the corresponding TimeZone
-//     * object.
-//     * @param country a two-letter ISO 3166 country code, or <code>null</code>
-//     * to return zones not associated with any country
-//     * @return an array of IDs for system TimeZones in the given
-//     * country.  If there are none, return a zero-length array.
-//     * @stable ICU 2.0
-//     */
-//    public static String[] getAvailableIDs(String country) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Return a new String array containing all system TimeZone IDs.
-     * These IDs (and only these IDs) may be passed to
-     * <code>get()</code> to construct the corresponding TimeZone
-     * object.
-     * @return an array of all system TimeZone IDs
-     * @stable ICU 2.0
-     */
-    public static String[] getAvailableIDs() {
-        return java.util.TimeZone.getAvailableIDs();
-    }
-
-//    /**
-//     * {@icu} Returns the number of IDs in the equivalency group that
-//     * includes the given ID.  An equivalency group contains zones
-//     * that have the same GMT offset and rules.
-//     *
-//     * <p>The returned count includes the given ID; it is always >= 1
-//     * for valid IDs.  The given ID must be a system time zone.  If it
-//     * is not, returns zero.
-//     * @param id a system time zone ID
-//     * @return the number of zones in the equivalency group containing
-//     * 'id', or zero if 'id' is not a valid system ID
-//     * @see #getEquivalentID
-//     * @stable ICU 2.0
-//     */
-//    public static int countEquivalentIDs(String id) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * Returns an ID in the equivalency group that
-//     * includes the given ID.  An equivalency group contains zones
-//     * that have the same GMT offset and rules.
-//     *
-//     * <p>The given index must be in the range 0..n-1, where n is the
-//     * value returned by <code>countEquivalentIDs(id)</code>.  For
-//     * some value of 'index', the returned value will be equal to the
-//     * given id.  If the given id is not a valid system time zone, or
-//     * if 'index' is out of range, then returns an empty string.
-//     * @param id a system time zone ID
-//     * @param index a value from 0 to n-1, where n is the value
-//     * returned by <code>countEquivalentIDs(id)</code>
-//     * @return the ID of the index-th zone in the equivalency group
-//     * containing 'id', or an empty string if 'id' is not a valid
-//     * system ID or 'index' is out of range
-//     * @see #countEquivalentIDs
-//     * @stable ICU 2.0
-//     */
-//    public static String getEquivalentID(String id, int index) {
-//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
-//    }
-
-    /**
-     * Gets the default <code>TimeZone</code> for this host.
-     * The source of the default <code>TimeZone</code>
-     * may vary with implementation.
-     * @return a default <code>TimeZone</code>.
-     * @stable ICU 2.0
-     */
-    public static TimeZone getDefault() {
-        return new TimeZone(java.util.TimeZone.getDefault());
-    }
-
-    /**
-     * Sets the <code>TimeZone</code> that is
-     * returned by the <code>getDefault</code> method.  If <code>zone</code>
-     * is null, reset the default to the value it had originally when the
-     * VM first started.
-     * @param tz the new default time zone
-     * @stable ICU 2.0
-     */
-    public static void setDefault(TimeZone tz) {
-        java.util.TimeZone.setDefault(tz.timeZone);
-    }
-
-    /**
-     * Returns true if this zone has the same rule and offset as another zone.
-     * That is, if this zone differs only in ID, if at all.  Returns false
-     * if the other zone is null.
-     * @param other the <code>TimeZone</code> object to be compared with
-     * @return true if the other zone is not null and is the same as this one,
-     * with the possible exception of the ID
-     * @stable ICU 2.0
-     */
-    public boolean hasSameRules(TimeZone other) {
-        return timeZone.hasSameRules(other.timeZone);
-    }
-
-    /**
-     * Overrides clone.
-     * @stable ICU 2.0
-     */
-    public Object clone() {
-        return new TimeZone((java.util.TimeZone)timeZone.clone());
-    }
-
-    /**
-     * Overrides equals.
-     * @stable ICU 3.6
-     */
-    public boolean equals(Object obj){
-        try {
-            return timeZone.equals(((TimeZone)obj).timeZone);
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    /**
-     * Overrides hashCode.
-     * @stable ICU 3.6
-     */
-    public int hashCode(){
-        return timeZone.hashCode();
-    }
-
-//    /**
-//     * {@icu} Returns the time zone data version currently used by ICU.
-//     *
-//     * @return the version string, such as "2007f"
-//     * @throws MissingResourceException if ICU time zone resource bundle
-//     * is missing or the version information is not available.
-//     *
-//     * @stable ICU 3.8
-//     */
-//    public static synchronized String getTZDataVersion() {
-//        throw new UnsupportedOperationException("Method not supproted by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the canonical system time zone ID or the normalized
-//     * custom time zone ID for the given time zone ID.
-//     * @param id The input time zone ID to be canonicalized.
-//     * @return The canonical system time zone ID or the custom time zone ID
-//     * in normalized format for the given time zone ID.  When the given time zone ID
-//     * is neither a known system time zone ID nor a valid custom time zone ID,
-//     * null is returned.
-//     * @stable ICU 4.0
-//     */
-//    public static String getCanonicalID(String id) {
-//        throw new UnsupportedOperationException("Method not supproted by com.ibm.icu.base");
-//    }
-
-//    /**
-//     * {@icu} Returns the canonical system time zone ID or the normalized
-//     * custom time zone ID for the given time zone ID.
-//     * @param id The input time zone ID to be canonicalized.
-//     * @param isSystemID When non-null boolean array is specified and
-//     * the given ID is a known system time zone ID, true is set to <code>isSystemID[0]</code>
-//     * @return The canonical system time zone ID or the custom time zone ID
-//     * in normalized format for the given time zone ID.  When the given time zone ID
-//     * is neither a known system time zone ID nor a valid custom time zone ID,
-//     * null is returned.
-//     * @stable ICU 4.0
-//     */
-//    public static String getCanonicalID(String id, boolean[] isSystemID) {
-//        throw new UnsupportedOperationException("Method not supproted by com.ibm.icu.base");
-//    }
-
-//    /** 
-//     * {@icu} Returns the region code associated with the given 
-//     * system time zone ID. The region code is either ISO 3166 
-//     * 2-letter country code or UN M.49 3-digit area code. 
-//     * When the time zone is not associated with a specific location, 
-//     * for example - "Etc/UTC", "EST5EDT", then this method returns 
-//     * "001" (UN M.49 area code for World). 
-//     * @param id the system time zone ID. 
-//     * @return the region code associated with the given 
-//     * system time zone ID. 
-//     * @throws IllegalArgumentException if <code>id</code> is not a known system ID. 
-//     * @see #getAvailableIDs(String) 
-//     * 
-//     * @draft ICU 4.8
-//     * @provisional This API might change or be removed in a future release.
-//     */ 
-//    public static String getRegion(String id) {
-//    	throw new UnsupportedOperationException("Method not supproted by com.ibm.icu.base");
-//    }
-
-    private transient boolean isFrozen = false;
-
-    /**
-     * {@inheritDoc}
-     * @draft ICU 49
-     * @provisional This API might change or be removed in a future release.
-     */
-    public boolean isFrozen() {
-        return isFrozen;
-    }
-
-    /**
-     * {@inheritDoc}
-     * @draft ICU 49
-     * @provisional This API might change or be removed in a future release.
-     */
-    public TimeZone freeze() {
-        isFrozen = true;
-        return this;
-    }
-
-    /**
-     * {@inheritDoc}
-     * @draft ICU 49
-     * @provisional This API might change or be removed in a future release.
-     */
-    public TimeZone cloneAsThawed() {
-        try {
-            TimeZone other = (TimeZone) super.clone();
-            other.isFrozen = false;
-            return other;
-        } catch (CloneNotSupportedException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-}
-
-//eof
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/ULocale.java b/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/ULocale.java
deleted file mode 100644
index 4e0fbe0..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.base/src/com/ibm/icu/util/ULocale.java
+++ /dev/null
@@ -1,4377 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
-******************************************************************************
-* Copyright (C) 2003-2012, International Business Machines Corporation and   *
-* others. All Rights Reserved.                                               *
-******************************************************************************
-*/
-
-package com.ibm.icu.util;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.text.ParseException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.MissingResourceException;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-import com.ibm.icu.impl.ICUCache;
-import com.ibm.icu.impl.LocaleIDParser;
-import com.ibm.icu.impl.LocaleIDs;
-import com.ibm.icu.impl.LocaleUtility;
-import com.ibm.icu.impl.SimpleCache;
-import com.ibm.icu.impl.locale.AsciiUtil;
-import com.ibm.icu.impl.locale.BaseLocale;
-import com.ibm.icu.impl.locale.Extension;
-import com.ibm.icu.impl.locale.InternalLocaleBuilder;
-import com.ibm.icu.impl.locale.LanguageTag;
-import com.ibm.icu.impl.locale.LocaleExtensions;
-import com.ibm.icu.impl.locale.LocaleSyntaxException;
-import com.ibm.icu.impl.locale.ParseStatus;
-import com.ibm.icu.impl.locale.UnicodeLocaleExtension;
-
-/**
- * {@icuenhanced java.util.Locale}.{@icu _usage_}
- *
- * A class analogous to {@link java.util.Locale} that provides additional
- * support for ICU protocol.  In ICU 3.0 this class is enhanced to support
- * RFC 3066 language identifiers.
- *
- * <p>Many classes and services in ICU follow a factory idiom, in
- * which a factory method or object responds to a client request with
- * an object.  The request includes a locale (the <i>requested</i>
- * locale), and the returned object is constructed using data for that
- * locale.  The system may lack data for the requested locale, in
- * which case the locale fallback mechanism will be invoked until a
- * populated locale is found (the <i>valid</i> locale).  Furthermore,
- * even when a populated locale is found (the <i>valid</i> locale),
- * further fallback may be required to reach a locale containing the
- * specific data required by the service (the <i>actual</i> locale).
- *
- * <p>ULocale performs <b>'normalization'</b> and <b>'canonicalization'</b> of locale ids.
- * Normalization 'cleans up' ICU locale ids as follows:
- * <ul>
- * <li>language, script, country, variant, and keywords are properly cased<br>
- * (lower, title, upper, upper, and lower case respectively)</li>
- * <li>hyphens used as separators are converted to underscores</li>
- * <li>three-letter language and country ids are converted to two-letter
- * equivalents where available</li>
- * <li>surrounding spaces are removed from keywords and values</li>
- * <li>if there are multiple keywords, they are put in sorted order</li>
- * </ul>
- * Canonicalization additionally performs the following:
- * <ul>
- * <li>POSIX ids are converted to ICU format IDs</li>
- * <li>Legacy language tags (marked as “Type: grandfathered” in BCP 47)
- * are converted to ICU standard form</li>
- * <li>'PREEURO' and 'EURO' variants are converted to currency keyword form,
- * with the currency
- * id appropriate to the country of the locale (for PREEURO) or EUR (for EURO).
- * </ul>
- * All ULocale constructors automatically normalize the locale id.  To handle
- * POSIX ids, <code>canonicalize</code> can be called to convert the id
- * to canonical form, or the <code>canonicalInstance</code> factory method
- * can be called.</p>
- *
- * <p>This class provides selectors {@link #VALID_LOCALE} and {@link
- * #ACTUAL_LOCALE} intended for use in methods named
- * <tt>getLocale()</tt>.  These methods exist in several ICU classes,
- * including {@link com.ibm.icu.util.Calendar}, {@link
- * com.ibm.icu.util.Currency}, {@link com.ibm.icu.text.UFormat},
- * {@link com.ibm.icu.text.BreakIterator},
- * <a href="../text/Collator.html" title="class in com.ibm.icu.text"><code>Collator</code></a>,
- * {@link com.ibm.icu.text.DateFormatSymbols}, and {@link
- * com.ibm.icu.text.DecimalFormatSymbols} and their subclasses, if
- * any.  Once an object of one of these classes has been created,
- * <tt>getLocale()</tt> may be called on it to determine the valid and
- * actual locale arrived at during the object's construction.
- *
- * <p>Note: The <i>actual</i> locale is returned correctly, but the <i>valid</i>
- * locale is not, in most cases.
- *
- * @see java.util.Locale
- * @author weiv
- * @author Alan Liu
- * @author Ram Viswanadha
- * @stable ICU 2.8
- */
-public final class ULocale implements Serializable {
-    // using serialver from jdk1.4.2_05
-    private static final long serialVersionUID = 3715177670352309217L;
-
-    /**
-     * Useful constant for language.
-     * @stable ICU 3.0
-     */
-    public static final ULocale ENGLISH = new ULocale("en", Locale.ENGLISH);
-
-    /**
-     * Useful constant for language.
-     * @stable ICU 3.0
-     */
-    public static final ULocale FRENCH = new ULocale("fr", Locale.FRENCH);
-
-    /**
-     * Useful constant for language.
-     * @stable ICU 3.0
-     */
-    public static final ULocale GERMAN = new ULocale("de", Locale.GERMAN);
-
-    /**
-     * Useful constant for language.
-     * @stable ICU 3.0
-     */
-    public static final ULocale ITALIAN = new ULocale("it", Locale.ITALIAN);
-
-    /**
-     * Useful constant for language.
-     * @stable ICU 3.0
-     */
-    public static final ULocale JAPANESE = new ULocale("ja", Locale.JAPANESE);
-
-    /**
-     * Useful constant for language.
-     * @stable ICU 3.0
-     */
-    public static final ULocale KOREAN = new ULocale("ko", Locale.KOREAN);
-
-    /**
-     * Useful constant for language.
-     * @stable ICU 3.0
-     */
-    public static final ULocale CHINESE = new ULocale("zh", Locale.CHINESE);
-
-    /**
-     * Useful constant for language.
-     * @stable ICU 3.0
-     */
-    public static final ULocale SIMPLIFIED_CHINESE = new ULocale("zh_Hans", Locale.CHINESE);
-
-    /**
-     * Useful constant for language.
-     * @stable ICU 3.0
-     */
-    public static final ULocale TRADITIONAL_CHINESE = new ULocale("zh_Hant", Locale.CHINESE);
-
-    /**
-     * Useful constant for country/region.
-     * @stable ICU 3.0
-     */
-    public static final ULocale FRANCE = new ULocale("fr_FR", Locale.FRANCE);
-
-    /**
-     * Useful constant for country/region.
-     * @stable ICU 3.0
-     */
-    public static final ULocale GERMANY = new ULocale("de_DE", Locale.GERMANY);
-
-    /**
-     * Useful constant for country/region.
-     * @stable ICU 3.0
-     */
-    public static final ULocale ITALY = new ULocale("it_IT", Locale.ITALY);
-
-    /**
-     * Useful constant for country/region.
-     * @stable ICU 3.0
-     */
-    public static final ULocale JAPAN = new ULocale("ja_JP", Locale.JAPAN);
-
-    /**
-     * Useful constant for country/region.
-     * @stable ICU 3.0
-     */
-    public static final ULocale KOREA = new ULocale("ko_KR", Locale.KOREA);
-
-    /**
-     * Useful constant for country/region.
-     * @stable ICU 3.0
-     */
-    public static final ULocale CHINA = new ULocale("zh_Hans_CN", Locale.CHINA);
-
-    /**
-     * Useful constant for country/region.
-     * @stable ICU 3.0
-     */
-    public static final ULocale PRC = CHINA;
-
-    /**
-     * Useful constant for country/region.
-     * @stable ICU 3.0
-     */
-    public static final ULocale TAIWAN = new ULocale("zh_Hant_TW", Locale.TAIWAN);
-
-    /**
-     * Useful constant for country/region.
-     * @stable ICU 3.0
-     */
-    public static final ULocale UK = new ULocale("en_GB", Locale.UK);
-
-    /**
-     * Useful constant for country/region.
-     * @stable ICU 3.0
-     */
-    public static final ULocale US = new ULocale("en_US", Locale.US);
-
-    /**
-     * Useful constant for country/region.
-     * @stable ICU 3.0
-     */
-    public static final ULocale CANADA = new ULocale("en_CA", Locale.CANADA);
-
-    /**
-     * Useful constant for country/region.
-     * @stable ICU 3.0
-     */
-    public static final ULocale CANADA_FRENCH = new ULocale("fr_CA", Locale.CANADA_FRENCH);
-
-    /**
-     * Handy constant.
-     */
-    private static final String EMPTY_STRING = "";
-
-    // Used in both ULocale and LocaleIDParser, so moved up here.
-    private static final char UNDERSCORE            = '_';
-
-    // default empty locale
-    private static final Locale EMPTY_LOCALE = new Locale("", "");
-
-    // special keyword key for Unicode locale attributes
-    private static final String LOCALE_ATTRIBUTE_KEY = "attribute";
-
-    /**
-     * The root ULocale.
-     * @stable ICU 2.8
-     */
-    public static final ULocale ROOT = new ULocale("", EMPTY_LOCALE);
-
-    /**
-     * Enum for locale categories. These locale categories are used to get/set the default locale for
-     * the specific functionality represented by the category.
-     * @stable ICU 49
-     */
-    public enum Category {
-        /**
-         * Category used to represent the default locale for displaying user interfaces.
-         * @stable ICU 49
-         */
-        DISPLAY,
-        /**
-         * Category used to represent the default locale for formatting date, number and/or currency.
-         * @stable ICU 49
-         */
-        FORMAT
-    }
-
-    private static final SimpleCache<Locale, ULocale> CACHE = new SimpleCache<Locale, ULocale>();
-
-    /**
-     * Cache the locale.
-     */
-    private transient volatile Locale locale;
-
-    /**
-     * The raw localeID that we were passed in.
-     */
-    private String localeID;
-
-    /**
-     * Cache the locale data container fields.
-     * In future, we want to use them as the primary locale identifier storage.
-     */
-    private transient volatile BaseLocale baseLocale;
-    private transient volatile LocaleExtensions extensions;
-
-
-    private static String[][] CANONICALIZE_MAP;
-    private static String[][] variantsToKeywords;
-
-    private static void initCANONICALIZE_MAP() {
-        if (CANONICALIZE_MAP == null) {
-            /**
-             * This table lists pairs of locale ids for canonicalization.  The
-             * The 1st item is the normalized id. The 2nd item is the
-             * canonicalized id. The 3rd is the keyword. The 4th is the keyword value.
-             */
-            String[][] tempCANONICALIZE_MAP = {
-//              { EMPTY_STRING,     "en_US_POSIX", null, null }, /* .NET name */
-                { "C",              "en_US_POSIX", null, null }, /* POSIX name */
-                { "art_LOJBAN",     "jbo", null, null }, /* registered name */
-                { "az_AZ_CYRL",     "az_Cyrl_AZ", null, null }, /* .NET name */
-                { "az_AZ_LATN",     "az_Latn_AZ", null, null }, /* .NET name */
-                { "ca_ES_PREEURO",  "ca_ES", "currency", "ESP" },
-                { "cel_GAULISH",    "cel__GAULISH", null, null }, /* registered name */
-                { "de_1901",        "de__1901", null, null }, /* registered name */
-                { "de_1906",        "de__1906", null, null }, /* registered name */
-                { "de__PHONEBOOK",  "de", "collation", "phonebook" }, /* Old ICU name */
-                { "de_AT_PREEURO",  "de_AT", "currency", "ATS" },
-                { "de_DE_PREEURO",  "de_DE", "currency", "DEM" },
-                { "de_LU_PREEURO",  "de_LU", "currency", "EUR" },
-                { "el_GR_PREEURO",  "el_GR", "currency", "GRD" },
-                { "en_BOONT",       "en__BOONT", null, null }, /* registered name */
-                { "en_SCOUSE",      "en__SCOUSE", null, null }, /* registered name */
-                { "en_BE_PREEURO",  "en_BE", "currency", "BEF" },
-                { "en_IE_PREEURO",  "en_IE", "currency", "IEP" },
-                { "es__TRADITIONAL", "es", "collation", "traditional" }, /* Old ICU name */
-                { "es_ES_PREEURO",  "es_ES", "currency", "ESP" },
-                { "eu_ES_PREEURO",  "eu_ES", "currency", "ESP" },
-                { "fi_FI_PREEURO",  "fi_FI", "currency", "FIM" },
-                { "fr_BE_PREEURO",  "fr_BE", "currency", "BEF" },
-                { "fr_FR_PREEURO",  "fr_FR", "currency", "FRF" },
-                { "fr_LU_PREEURO",  "fr_LU", "currency", "LUF" },
-                { "ga_IE_PREEURO",  "ga_IE", "currency", "IEP" },
-                { "gl_ES_PREEURO",  "gl_ES", "currency", "ESP" },
-                { "hi__DIRECT",     "hi", "collation", "direct" }, /* Old ICU name */
-                { "it_IT_PREEURO",  "it_IT", "currency", "ITL" },
-                { "ja_JP_TRADITIONAL", "ja_JP", "calendar", "japanese" },
-//              { "nb_NO_NY",       "nn_NO", null, null },
-                { "nl_BE_PREEURO",  "nl_BE", "currency", "BEF" },
-                { "nl_NL_PREEURO",  "nl_NL", "currency", "NLG" },
-                { "pt_PT_PREEURO",  "pt_PT", "currency", "PTE" },
-                { "sl_ROZAJ",       "sl__ROZAJ", null, null }, /* registered name */
-                { "sr_SP_CYRL",     "sr_Cyrl_RS", null, null }, /* .NET name */
-                { "sr_SP_LATN",     "sr_Latn_RS", null, null }, /* .NET name */
-                { "sr_YU_CYRILLIC", "sr_Cyrl_RS", null, null }, /* Linux name */
-                { "th_TH_TRADITIONAL", "th_TH", "calendar", "buddhist" }, /* Old ICU name */
-                { "uz_UZ_CYRILLIC", "uz_Cyrl_UZ", null, null }, /* Linux name */
-                { "uz_UZ_CYRL",     "uz_Cyrl_UZ", null, null }, /* .NET name */
-                { "uz_UZ_LATN",     "uz_Latn_UZ", null, null }, /* .NET name */
-                { "zh_CHS",         "zh_Hans", null, null }, /* .NET name */
-                { "zh_CHT",         "zh_Hant", null, null }, /* .NET name */
-                { "zh_GAN",         "zh__GAN", null, null }, /* registered name */
-                { "zh_GUOYU",       "zh", null, null }, /* registered name */
-                { "zh_HAKKA",       "zh__HAKKA", null, null }, /* registered name */
-                { "zh_MIN",         "zh__MIN", null, null }, /* registered name */
-                { "zh_MIN_NAN",     "zh__MINNAN", null, null }, /* registered name */
-                { "zh_WUU",         "zh__WUU", null, null }, /* registered name */
-                { "zh_XIANG",       "zh__XIANG", null, null }, /* registered name */
-                { "zh_YUE",         "zh__YUE", null, null } /* registered name */
-            };
-
-            synchronized (ULocale.class) {
-                if (CANONICALIZE_MAP == null) {
-                    CANONICALIZE_MAP = tempCANONICALIZE_MAP;
-                }
-            }
-        }
-        if (variantsToKeywords == null) {
-            /**
-             * This table lists pairs of locale ids for canonicalization.  The
-             * The first item is the normalized variant id.
-             */
-            String[][] tempVariantsToKeywords = {
-                    { "EURO",   "currency", "EUR" },
-                    { "PINYIN", "collation", "pinyin" }, /* Solaris variant */
-                    { "STROKE", "collation", "stroke" }  /* Solaris variant */
-            };
-
-            synchronized (ULocale.class) {
-                if (variantsToKeywords == null) {
-                    variantsToKeywords = tempVariantsToKeywords;
-                }
-            }
-        }
-    }
-
-    /**
-     * Private constructor used by static initializers.
-     */
-    private ULocale(String localeID, Locale locale) {
-        this.localeID = localeID;
-        this.locale = locale;
-    }
-
-    /**
-     * Construct a ULocale object from a {@link java.util.Locale}.
-     * @param loc a JDK locale
-     */
-    private ULocale(Locale loc) {
-        this.localeID = getName(forLocale(loc).toString());
-        this.locale = loc;
-    }
-
-    /**
-     * {@icu} Returns a ULocale object for a {@link java.util.Locale}.
-     * The ULocale is canonicalized.
-     * @param loc a JDK locale
-     * @stable ICU 3.2
-     */
-    public static ULocale forLocale(Locale loc) {
-        if (loc == null) {
-            return null;
-        }
-        ULocale result = CACHE.get(loc);
-        if (result == null) {
-            result = JDKLocaleHelper.toULocale(loc);
-            CACHE.put(loc, result);
-        }
-        return result;
-    }
-
-    /**
-     * {@icu} Constructs a ULocale from a RFC 3066 locale ID. The locale ID consists
-     * of optional language, script, country, and variant fields in that order,
-     * separated by underscores, followed by an optional keyword list.  The
-     * script, if present, is four characters long-- this distinguishes it
-     * from a country code, which is two characters long.  Other fields
-     * are distinguished by position as indicated by the underscores.  The
-     * start of the keyword list is indicated by '@', and consists of two
-     * or more keyword/value pairs separated by semicolons(';').
-     * 
-     * <p>This constructor does not canonicalize the localeID.  So, for
-     * example, "zh__pinyin" remains unchanged instead of converting
-     * to "zh@collation=pinyin".  By default ICU only recognizes the
-     * latter as specifying pinyin collation.  Use {@link #createCanonical}
-     * or {@link #canonicalize} if you need to canonicalize the localeID.
-     *
-     * @param localeID string representation of the locale, e.g:
-     * "en_US", "sy_Cyrl_YU", "zh__pinyin", "es_ES@currency=EUR;collation=traditional"
-     * @stable ICU 2.8
-     */
-    public ULocale(String localeID) {
-        this.localeID = getName(localeID);
-    }
-
-    /**
-     * Convenience overload of ULocale(String, String, String) for
-     * compatibility with java.util.Locale.
-     * @see #ULocale(String, String, String)
-     * @stable ICU 3.4
-     */
-    public ULocale(String a, String b) {
-        this(a, b, null);
-    }
-
-    /**
-     * Constructs a ULocale from a localeID constructed from the three 'fields' a, b, and
-     * c.  These fields are concatenated using underscores to form a localeID of the form
-     * a_b_c, which is then handled like the localeID passed to <code>ULocale(String
-     * localeID)</code>.
-     *
-     * <p>Java locale strings consisting of language, country, and
-     * variant will be handled by this form, since the country code
-     * (being shorter than four letters long) will not be interpreted
-     * as a script code.  If a script code is present, the final
-     * argument ('c') will be interpreted as the country code.  It is
-     * recommended that this constructor only be used to ease porting,
-     * and that clients instead use the single-argument constructor
-     * when constructing a ULocale from a localeID.
-     * @param a first component of the locale id
-     * @param b second component of the locale id
-     * @param c third component of the locale id
-     * @see #ULocale(String)
-     * @stable ICU 3.0
-     */
-    public ULocale(String a, String b, String c) {
-        localeID = getName(lscvToID(a, b, c, EMPTY_STRING));
-    }
-
-    /**
-     * {@icu} Creates a ULocale from the id by first canonicalizing the id.
-     * @param nonCanonicalID the locale id to canonicalize
-     * @return the locale created from the canonical version of the ID.
-     * @stable ICU 3.0
-     */
-    public static ULocale createCanonical(String nonCanonicalID) {
-        return new ULocale(canonicalize(nonCanonicalID), (Locale)null);
-    }
-
-    private static String lscvToID(String lang, String script, String country, String variant) {
-        StringBuilder buf = new StringBuilder();
-
-        if (lang != null && lang.length() > 0) {
-            buf.append(lang);
-        }
-        if (script != null && script.length() > 0) {
-            buf.append(UNDERSCORE);
-            buf.append(script);
-        }
-        if (country != null && country.length() > 0) {
-            buf.append(UNDERSCORE);
-            buf.append(country);
-        }
-        if (variant != null && variant.length() > 0) {
-            if (country == null || country.length() == 0) {
-                buf.append(UNDERSCORE);
-            }
-            buf.append(UNDERSCORE);
-            buf.append(variant);
-        }
-        return buf.toString();
-    }
-
-    /**
-     * {@icu} Converts this ULocale object to a {@link java.util.Locale}.
-     * @return a JDK locale that either exactly represents this object
-     * or is the closest approximation.
-     * @stable ICU 2.8
-     */
-    public Locale toLocale() {
-        if (locale == null) {
-            locale = JDKLocaleHelper.toLocale(this);
-        }
-        return locale;
-    }
-
-    private static ICUCache<String, String> nameCache = new SimpleCache<String, String>();
-
-    /**
-     * Keep our own default ULocale.
-     */
-    private static Locale defaultLocale = Locale.getDefault();
-    private static ULocale defaultULocale = forLocale(defaultLocale);
-
-    private static Locale[] defaultCategoryLocales = new Locale[Category.values().length];
-    private static ULocale[] defaultCategoryULocales = new ULocale[Category.values().length];
-
-    static {
-        for (Category cat: Category.values()) {
-            int idx = cat.ordinal();
-            defaultCategoryLocales[idx] = JDKLocaleHelper.getDefault(cat);
-            defaultCategoryULocales[idx] = forLocale(defaultCategoryLocales[idx]);
-        }
-    }
-
-    /**
-     * Returns the current default ULocale.
-     * @return the default ULocale.
-     * @stable ICU 2.8
-     */
-    public static ULocale getDefault() {
-        synchronized (ULocale.class) {
-            if (defaultULocale == null) {
-                // When Java's default locale has extensions (such as ja-JP-u-ca-japanese),
-                // Locale -> ULocale mapping requires BCP47 keyword mapping data that is currently
-                // stored in a resource bundle. However, UResourceBundle currently requires
-                // non-null default ULocale. For now, this implementation returns ULocale.ROOT
-                // to avoid the problem.
-
-                // TODO: Consider moving BCP47 mapping data out of resource bundle later.
-
-                return ULocale.ROOT;
-            }
-            Locale currentDefault = Locale.getDefault();
-            if (!defaultLocale.equals(currentDefault)) {
-                defaultLocale = currentDefault;
-                defaultULocale = forLocale(currentDefault);
-
-                if (!JDKLocaleHelper.isJava7orNewer()) {
-                    // Detected Java default Locale change.
-                    // We need to update category defaults to match the
-                    // Java 7's behavior on Java 6 or older environment.
-                    for (Category cat : Category.values()) {
-                        int idx = cat.ordinal();
-                        defaultCategoryLocales[idx] = currentDefault;
-                        defaultCategoryULocales[idx] = forLocale(currentDefault);
-                    }
-                }
-            }
-            return defaultULocale;
-        }
-    }
-
-    /**
-     * {@icu} Sets the default ULocale.  This also sets the default Locale.
-     * If the caller does not have write permission to the
-     * user.language property, a security exception will be thrown,
-     * and the default ULocale will remain unchanged.
-     * <p>
-     * By setting the default ULocale with this method, all of the default category locales
-     * are also set to the specified default ULocale.
-     * @param newLocale the new default locale
-     * @throws SecurityException if a security manager exists and its
-     *        <code>checkPermission</code> method doesn't allow the operation.
-     * @throws NullPointerException if <code>newLocale</code> is null
-     * @see SecurityManager#checkPermission(java.security.Permission)
-     * @see java.util.PropertyPermission
-     * @see ULocale#setDefault(Category, ULocale)
-     * @stable ICU 3.0
-     */
-    public static synchronized void setDefault(ULocale newLocale){
-        defaultLocale = newLocale.toLocale();
-        Locale.setDefault(defaultLocale);
-        defaultULocale = newLocale;
-        // This method also updates all category default locales
-        for (Category cat : Category.values()) {
-            setDefault(cat, newLocale);
-        }
-    }
-
-    /**
-     * Returns the current default ULocale for the specified category.
-     * 
-     * @param category the category
-     * @return the default ULocale for the specified category.
-     * @stable ICU 49
-     */
-    public static ULocale getDefault(Category category) {
-        synchronized (ULocale.class) {
-            int idx = category.ordinal();
-            if (defaultCategoryULocales[idx] == null) {
-                // Just in case this method is called during ULocale class
-                // initialization. Unlike getDefault(), we do not have
-                // cyclic dependency for category default.
-                return ULocale.ROOT;
-            }
-            if (JDKLocaleHelper.isJava7orNewer()) {
-                Locale currentCategoryDefault = JDKLocaleHelper.getDefault(category);
-                if (!defaultCategoryLocales[idx].equals(currentCategoryDefault)) {
-                    defaultCategoryLocales[idx] = currentCategoryDefault;
-                    defaultCategoryULocales[idx] = forLocale(currentCategoryDefault);
-                }
-            } else {
-                // java.util.Locale.setDefault(Locale) in Java 7 updates
-                // category locale defaults. On Java 6 or older environment,
-                // ICU4J checks if the default locale has changed and update
-                // category ULocales here if necessary.
-                
-                // Note: When java.util.Locale.setDefault(Locale) is called
-                // with a Locale same with the previous one, Java 7 still
-                // updates category locale defaults. On Java 6 or older env,
-                // there is no good way to detect the event, ICU4J simply
-                // check if the default Java Locale has changed since last
-                // time.
-
-                Locale currentDefault = Locale.getDefault();
-                if (!defaultLocale.equals(currentDefault)) {
-                    defaultLocale = currentDefault;
-                    defaultULocale = forLocale(currentDefault);
-
-                    for (Category cat : Category.values()) {
-                        int tmpIdx = cat.ordinal();
-                        defaultCategoryLocales[tmpIdx] = currentDefault;
-                        defaultCategoryULocales[tmpIdx] = forLocale(currentDefault);
-                    }
-                }
-                
-                // No synchronization with JDK Locale, because category default
-                // is not supported in Java 6 or older versions
-            }
-            return defaultCategoryULocales[idx];
-        }
-    }
-
-    /**
-     * Sets the default <code>ULocale</code> for the specified <code>Category</code>.
-     * This also sets the default <code>Locale</code> for the specified <code>Category</code>
-     * of the JVM. If the caller does not have write permission to the
-     * user.language property, a security exception will be thrown,
-     * and the default ULocale for the specified Category will remain unchanged.
-     * 
-     * @param category the specified category to set the default locale
-     * @param newLocale the new default locale
-     * @see SecurityManager#checkPermission(java.security.Permission)
-     * @see java.util.PropertyPermission
-     * @stable ICU 49
-     */
-    public static synchronized void setDefault(Category category, ULocale newLocale) {
-        Locale newJavaDefault = newLocale.toLocale();
-        int idx = category.ordinal();
-        defaultCategoryULocales[idx] = newLocale;
-        defaultCategoryLocales[idx] = newJavaDefault;
-        JDKLocaleHelper.setDefault(category, newJavaDefault);
-    }
-
-    /**
-     * This is for compatibility with Locale-- in actuality, since ULocale is
-     * immutable, there is no reason to clone it, so this API returns 'this'.
-     * @stable ICU 3.0
-     */
-    public Object clone() {
-        return this;
-    }
-
-    /**
-     * Returns the hashCode.
-     * @stable ICU 3.0
-     */
-    public int hashCode() {
-        return localeID.hashCode();
-    }
-
-    /**
-     * Returns true if the other object is another ULocale with the
-     * same full name, or is a String localeID that matches the full name.
-     * Note that since names are not canonicalized, two ULocales that
-     * function identically might not compare equal.
-     *
-     * @return true if this Locale is equal to the specified object.
-     * @stable ICU 3.0
-     */
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof String) {
-            return localeID.equals((String)obj);
-        }
-        if (obj instanceof ULocale) {
-            return localeID.equals(((ULocale)obj).localeID);
-        }
-        return false;
-    }
-
-    /**
-     * {@icunote} Unlike the Locale API, this returns an array of <code>ULocale</code>,
-     * not <code>Locale</code>.  Returns a list of all installed locales.
-     * @stable ICU 3.0
-     */
-    public static ULocale[] getAvailableLocales() {
-        //#com.ibm.icu.base
-        if (availableLocales == null) {
-            synchronized (ULocale.class) {
-                if (availableLocales == null) {
-                    Locale[] locales = Locale.getAvailableLocales();
-                    availableLocales = new ULocale[locales.length];
-                    for (int i = 0; i < locales.length; i++) {
-                        availableLocales[i] = ULocale.forLocale(locales[i]);
-                    }
-                }
-            }
-        }
-        return availableLocales.clone();
-    }
-    private static volatile ULocale[] availableLocales = null;
-
-    /**
-     * Returns a list of all 2-letter country codes defined in ISO 3166.
-     * Can be used to create Locales.
-     * @stable ICU 3.0
-     */
-    public static String[] getISOCountries() {
-        return LocaleIDs.getISOCountries();
-    }
-
-    /**
-     * Returns a list of all 2-letter language codes defined in ISO 639.
-     * Can be used to create Locales.
-     * [NOTE:  ISO 639 is not a stable standard-- some languages' codes have changed.
-     * The list this function returns includes both the new and the old codes for the
-     * languages whose codes have changed.]
-     * @stable ICU 3.0
-     */
-    public static String[] getISOLanguages() {
-        return LocaleIDs.getISOLanguages();
-    }
-
-    /**
-     * Returns the language code for this locale, which will either be the empty string
-     * or a lowercase ISO 639 code.
-     * @see #getDisplayLanguage()
-     * @see #getDisplayLanguage(ULocale)
-     * @stable ICU 3.0
-     */
-    public String getLanguage() {
-        return getLanguage(localeID);
-    }
-
-    /**
-     * Returns the language code for the locale ID,
-     * which will either be the empty string
-     * or a lowercase ISO 639 code.
-     * @see #getDisplayLanguage()
-     * @see #getDisplayLanguage(ULocale)
-     * @stable ICU 3.0
-     */
-    public static String getLanguage(String localeID) {
-        return new LocaleIDParser(localeID).getLanguage();
-    }
-
-    /**
-     * {@icu} Returns the script code for this locale, which might be the empty string.
-     * @see #getDisplayScript()
-     * @see #getDisplayScript(ULocale)
-     * @stable ICU 3.0
-     */
-    public String getScript() {
-        return getScript(localeID);
-    }
-
-    /**
-     * {@icu} Returns the script code for the specified locale, which might be the empty
-     * string.
-     * @see #getDisplayScript()
-     * @see #getDisplayScript(ULocale)
-     * @stable ICU 3.0
-     */
-    public static String getScript(String localeID) {
-        return new LocaleIDParser(localeID).getScript();
-    }
-
-    /**
-     * Returns the country/region code for this locale, which will either be the empty string
-     * or an uppercase ISO 3166 2-letter code.
-     * @see #getDisplayCountry()
-     * @see #getDisplayCountry(ULocale)
-     * @stable ICU 3.0
-     */
-    public String getCountry() {
-        return getCountry(localeID);
-    }
-
-    /**
-     * Returns the country/region code for this locale, which will either be the empty string
-     * or an uppercase ISO 3166 2-letter code.
-     * @param localeID The locale identification string.
-     * @see #getDisplayCountry()
-     * @see #getDisplayCountry(ULocale)
-     * @stable ICU 3.0
-     */
-    public static String getCountry(String localeID) {
-        return new LocaleIDParser(localeID).getCountry();
-    }
-
-    /**
-     * Returns the variant code for this locale, which might be the empty string.
-     * @see #getDisplayVariant()
-     * @see #getDisplayVariant(ULocale)
-     * @stable ICU 3.0
-     */
-    public String getVariant() {
-        return getVariant(localeID);
-    }
-
-    /**
-     * Returns the variant code for the specified locale, which might be the empty string.
-     * @see #getDisplayVariant()
-     * @see #getDisplayVariant(ULocale)
-     * @stable ICU 3.0
-     */
-    public static String getVariant(String localeID) {
-        return new LocaleIDParser(localeID).getVariant();
-    }
-
-    /**
-     * {@icu} Returns the fallback locale for the specified locale, which might be the
-     * empty string.
-     * @stable ICU 3.2
-     */
-    public static String getFallback(String localeID) {
-        return getFallbackString(getName(localeID));
-    }
-
-    /**
-     * {@icu} Returns the fallback locale for this locale.  If this locale is root,
-     * returns null.
-     * @stable ICU 3.2
-     */
-    public ULocale getFallback() {
-        if (localeID.length() == 0 || localeID.charAt(0) == '@') {
-            return null;
-        }
-        return new ULocale(getFallbackString(localeID), (Locale)null);
-    }
-
-    /**
-     * Returns the given (canonical) locale id minus the last part before the tags.
-     */
-    private static String getFallbackString(String fallback) {
-        int extStart = fallback.indexOf('@');
-        if (extStart == -1) {
-            extStart = fallback.length();
-        }
-        int last = fallback.lastIndexOf('_', extStart);
-        if (last == -1) {
-            last = 0;
-        } else {
-            // truncate empty segment
-            while (last > 0) {
-                if (fallback.charAt(last - 1) != '_') {
-                    break;
-                }
-                last--;
-            }
-        }
-        return fallback.substring(0, last) + fallback.substring(extStart);
-    }
-
-    /**
-     * {@icu} Returns the (normalized) base name for this locale.
-     * @return the base name as a String.
-     * @stable ICU 3.0
-     */
-    public String getBaseName() {
-        return getBaseName(localeID);
-    }
-
-    /**
-     * {@icu} Returns the (normalized) base name for the specified locale.
-     * @param localeID the locale ID as a string
-     * @return the base name as a String.
-     * @stable ICU 3.0
-     */
-    public static String getBaseName(String localeID){
-        if (localeID.indexOf('@') == -1) {
-            return localeID;
-        }
-        return new LocaleIDParser(localeID).getBaseName();
-    }
-
-    /**
-     * {@icu} Returns the (normalized) full name for this locale.
-     *
-     * @return String the full name of the localeID
-     * @stable ICU 3.0
-     */
-    public String getName() {
-        return localeID; // always normalized
-    }
-    
-    /**
-     * Gets the shortest length subtag's size.
-     *
-     * @param localeID
-     * @return The size of the shortest length subtag
-     **/
-    private static int getShortestSubtagLength(String localeID) {
-        int localeIDLength = localeID.length();
-        int length = localeIDLength;
-        boolean reset = true;
-        int tmpLength = 0;
-        
-        for (int i = 0; i < localeIDLength; i++) {
-            if (localeID.charAt(i) != '_' && localeID.charAt(i) != '-') {
-                if (reset) {
-                    reset = false;
-                    tmpLength = 0;
-                }
-                tmpLength++;
-            } else {
-                if (tmpLength != 0 && tmpLength < length) {
-                    length = tmpLength;
-                }
-                reset = true;
-            }
-        }
-        
-        return length;
-    }
-
-    /**
-     * {@icu} Returns the (normalized) full name for the specified locale.
-     *
-     * @param localeID the localeID as a string
-     * @return String the full name of the localeID
-     * @stable ICU 3.0
-     */
-    public static String getName(String localeID){
-        String tmpLocaleID;
-        // Convert BCP47 id if necessary
-        if (localeID != null && !localeID.contains("@") && getShortestSubtagLength(localeID) == 1) {
-            tmpLocaleID = forLanguageTag(localeID).getName();
-            if (tmpLocaleID.length() == 0) {
-                tmpLocaleID = localeID;
-            }
-        } else {
-            tmpLocaleID = localeID;
-        }
-        String name = nameCache.get(tmpLocaleID);
-        if (name == null) {
-            name = new LocaleIDParser(tmpLocaleID).getName();
-            nameCache.put(tmpLocaleID, name);
-        }
-        return name;
-    }
-
-    /**
-     * Returns a string representation of this object.
-     * @stable ICU 3.0
-     */
-    public String toString() {
-        return localeID;
-    }
-
-    /**
-     * {@icu} Returns an iterator over keywords for this locale.  If there
-     * are no keywords, returns null.
-     * @return iterator over keywords, or null if there are no keywords.
-     * @stable ICU 3.0
-     */
-    public Iterator<String> getKeywords() {
-        return getKeywords(localeID);
-    }
-
-    /**
-     * {@icu} Returns an iterator over keywords for the specified locale.  If there
-     * are no keywords, returns null.
-     * @return an iterator over the keywords in the specified locale, or null
-     * if there are no keywords.
-     * @stable ICU 3.0
-     */
-    public static Iterator<String> getKeywords(String localeID){
-        return new LocaleIDParser(localeID).getKeywords();
-    }
-
-    /**
-     * {@icu} Returns the value for a keyword in this locale. If the keyword is not
-     * defined, returns null.
-     * @param keywordName name of the keyword whose value is desired. Case insensitive.
-     * @return the value of the keyword, or null.
-     * @stable ICU 3.0
-     */
-    public String getKeywordValue(String keywordName){
-        return getKeywordValue(localeID, keywordName);
-    }
-
-    /**
-     * {@icu} Returns the value for a keyword in the specified locale. If the keyword is
-     * not defined, returns null.  The locale name does not need to be normalized.
-     * @param keywordName name of the keyword whose value is desired. Case insensitive.
-     * @return String the value of the keyword as a string
-     * @stable ICU 3.0
-     */
-    public static String getKeywordValue(String localeID, String keywordName) {
-        return new LocaleIDParser(localeID).getKeywordValue(keywordName);
-    }
-
-    /**
-     * {@icu} Returns the canonical name for the specified locale ID.  This is used to
-     * convert POSIX and other legacy IDs to standard ICU form.
-     * @param localeID the locale id
-     * @return the canonicalized id
-     * @stable ICU 3.0
-     */
-    public static String canonicalize(String localeID){
-        LocaleIDParser parser = new LocaleIDParser(localeID, true);
-        String baseName = parser.getBaseName();
-        boolean foundVariant = false;
-
-        // formerly, we always set to en_US_POSIX if the basename was empty, but
-        // now we require that the entire id be empty, so that "@foo=bar"
-        // will pass through unchanged.
-        // {dlf} I'd rather keep "" unchanged.
-        if (localeID.equals("")) {
-            return "";
-//              return "en_US_POSIX";
-        }
-
-        // we have an ID in the form xx_Yyyy_ZZ_KKKKK
-
-        initCANONICALIZE_MAP();
-
-        /* convert the variants to appropriate ID */
-        for (int i = 0; i < variantsToKeywords.length; i++) {
-            String[] vals = variantsToKeywords[i];
-            int idx = baseName.lastIndexOf("_" + vals[0]);
-            if (idx > -1) {
-                foundVariant = true;
-
-                baseName = baseName.substring(0, idx);
-                if (baseName.endsWith("_")) {
-                    baseName = baseName.substring(0, --idx);
-                }
-                parser.setBaseName(baseName);
-                parser.defaultKeywordValue(vals[1], vals[2]);
-                break;
-            }
-        }
-
-        /* See if this is an already known locale */
-        for (int i = 0; i < CANONICALIZE_MAP.length; i++) {
-            if (CANONICALIZE_MAP[i][0].equals(baseName)) {
-                foundVariant = true;
-
-                String[] vals = CANONICALIZE_MAP[i];
-                parser.setBaseName(vals[1]);
-                if (vals[2] != null) {
-                    parser.defaultKeywordValue(vals[2], vals[3]);
-                }
-                break;
-            }
-        }
-
-        /* total mondo hack for Norwegian, fortunately the main NY case is handled earlier */
-        if (!foundVariant) {
-            if (parser.getLanguage().equals("nb") && parser.getVariant().equals("NY")) {
-                parser.setBaseName(lscvToID("nn", parser.getScript(), parser.getCountry(), null));
-            }
-        }
-
-        return parser.getName();
-    }
-
-    /**
-     * Given a keyword and a value, return a new locale with an updated
-     * keyword and value.  If keyword is null, this removes all keywords from the locale id.
-     * Otherwise, if the value is null, this removes the value for this keyword from the
-     * locale id.  Otherwise, this adds/replaces the value for this keyword in the locale id.
-     * The keyword and value must not be empty.
-     * @param keyword the keyword to add/remove, or null to remove all keywords.
-     * @param value the value to add/set, or null to remove this particular keyword.
-     * @return the updated locale
-     * @stable ICU 3.2
-     */
-    public ULocale setKeywordValue(String keyword, String value) {
-        return new ULocale(setKeywordValue(localeID, keyword, value), (Locale)null);
-    }
-
-    /**
-     * Given a locale id, a keyword, and a value, return a new locale id with an updated
-     * keyword and value.  If keyword is null, this removes all keywords from the locale id.
-     * Otherwise, if the value is null, this removes the value for this keyword from the
-     * locale id.  Otherwise, this adds/replaces the value for this keyword in the locale id.
-     * The keyword and value must not be empty.
-     * @param localeID the locale id to modify
-     * @param keyword the keyword to add/remove, or null to remove all keywords.
-     * @param value the value to add/set, or null to remove this particular keyword.
-     * @return the updated locale id
-     * @stable ICU 3.2
-     */
-    public static String setKeywordValue(String localeID, String keyword, String value) {
-        LocaleIDParser parser = new LocaleIDParser(localeID);
-        parser.setKeywordValue(keyword, value);
-        return parser.getName();
-    }
-
-    /*
-     * Given a locale id, a keyword, and a value, return a new locale id with an updated
-     * keyword and value, if the keyword does not already have a value.  The keyword and
-     * value must not be null or empty.
-     * @param localeID the locale id to modify
-     * @param keyword the keyword to add, if not already present
-     * @param value the value to add, if not already present
-     * @return the updated locale id
-     */
-/*    private static String defaultKeywordValue(String localeID, String keyword, String value) {
-        LocaleIDParser parser = new LocaleIDParser(localeID);
-        parser.defaultKeywordValue(keyword, value);
-        return parser.getName();
-    }*/
-
-    /**
-     * Returns a three-letter abbreviation for this locale's language.  If the locale
-     * doesn't specify a language, returns the empty string.  Otherwise, returns
-     * a lowercase ISO 639-2/T language code.
-     * The ISO 639-2 language codes can be found on-line at
-     *   <a href="ftp://dkuug.dk/i18n/iso-639-2.txt"><code>ftp://dkuug.dk/i18n/iso-639-2.txt</code></a>
-     * @exception MissingResourceException Throws MissingResourceException if the
-     * three-letter language abbreviation is not available for this locale.
-     * @stable ICU 3.0
-     */
-    public String getISO3Language(){
-        return getISO3Language(localeID);
-    }
-
-    /**
-     * Returns a three-letter abbreviation for this locale's language.  If the locale
-     * doesn't specify a language, returns the empty string.  Otherwise, returns
-     * a lowercase ISO 639-2/T language code.
-     * The ISO 639-2 language codes can be found on-line at
-     *   <a href="ftp://dkuug.dk/i18n/iso-639-2.txt"><code>ftp://dkuug.dk/i18n/iso-639-2.txt</code></a>
-     * @exception MissingResourceException Throws MissingResourceException if the
-     * three-letter language abbreviation is not available for this locale.
-     * @stable ICU 3.0
-     */
-    public static String getISO3Language(String localeID) {
-        return LocaleIDs.getISO3Language(getLanguage(localeID));
-    }
-
-    /**
-     * Returns a three-letter abbreviation for this locale's country/region.  If the locale
-     * doesn't specify a country, returns the empty string.  Otherwise, returns
-     * an uppercase ISO 3166 3-letter country code.
-     * @exception MissingResourceException Throws MissingResourceException if the
-     * three-letter country abbreviation is not available for this locale.
-     * @stable ICU 3.0
-     */
-    public String getISO3Country() {
-        return getISO3Country(localeID);
-    }
-
-    /**
-     * Returns a three-letter abbreviation for this locale's country/region.  If the locale
-     * doesn't specify a country, returns the empty string.  Otherwise, returns
-     * an uppercase ISO 3166 3-letter country code.
-     * @exception MissingResourceException Throws MissingResourceException if the
-     * three-letter country abbreviation is not available for this locale.
-     * @stable ICU 3.0
-     */
-    public static String getISO3Country(String localeID) {
-        return LocaleIDs.getISO3Country(getCountry(localeID));
-    }
-
-    // display names
-
-    /**
-     * Returns this locale's language localized for display in the default <code>DISPLAY</code> locale.
-     * @return the localized language name.
-     * @see Category#DISPLAY
-     * @stable ICU 3.0
-     */
-    public String getDisplayLanguage() {
-        return getDisplayLanguageInternal(this, getDefault(Category.DISPLAY), false);
-    }
-
-    /**
-     * {@icu} Returns this locale's language localized for display in the provided locale.
-     * @param displayLocale the locale in which to display the name.
-     * @return the localized language name.
-     * @stable ICU 3.0
-     */
-    public String getDisplayLanguage(ULocale displayLocale) {
-        return getDisplayLanguageInternal(this, displayLocale, false);
-    }
-
-    /**
-     * Returns a locale's language localized for display in the provided locale.
-     * This is a cover for the ICU4C API.
-     * @param localeID the id of the locale whose language will be displayed
-     * @param displayLocaleID the id of the locale in which to display the name.
-     * @return the localized language name.
-     * @stable ICU 3.0
-     */
-    public static String getDisplayLanguage(String localeID, String displayLocaleID) {
-        return getDisplayLanguageInternal(new ULocale(localeID), new ULocale(displayLocaleID),
-                false);
-    }
-
-    /**
-     * Returns a locale's language localized for display in the provided locale.
-     * This is a cover for the ICU4C API.
-     * @param localeID the id of the locale whose language will be displayed.
-     * @param displayLocale the locale in which to display the name.
-     * @return the localized language name.
-     * @stable ICU 3.0
-     */
-    public static String getDisplayLanguage(String localeID, ULocale displayLocale) {
-        return getDisplayLanguageInternal(new ULocale(localeID), displayLocale, false);
-    }
-    /**
-     * {@icu} Returns this locale's language localized for display in the default <code>DISPLAY</code> locale.
-     * If a dialect name is present in the data, then it is returned.
-     * @return the localized language name.
-     * @see Category#DISPLAY
-     * @stable ICU 4.4
-     */
-    public String getDisplayLanguageWithDialect() {
-        return getDisplayLanguageInternal(this, getDefault(Category.DISPLAY), true);
-    }
-
-    /**
-     * {@icu} Returns this locale's language localized for display in the provided locale.
-     * If a dialect name is present in the data, then it is returned.
-     * @param displayLocale the locale in which to display the name.
-     * @return the localized language name.
-     * @stable ICU 4.4
-     */
-    public String getDisplayLanguageWithDialect(ULocale displayLocale) {
-        return getDisplayLanguageInternal(this, displayLocale, true);
-    }
-
-    /**
-     * {@icu} Returns a locale's language localized for display in the provided locale.
-     * If a dialect name is present in the data, then it is returned.
-     * This is a cover for the ICU4C API.
-     * @param localeID the id of the locale whose language will be displayed
-     * @param displayLocaleID the id of the locale in which to display the name.
-     * @return the localized language name.
-     * @stable ICU 4.4
-     */
-    public static String getDisplayLanguageWithDialect(String localeID, String displayLocaleID) {
-        return getDisplayLanguageInternal(new ULocale(localeID), new ULocale(displayLocaleID),
-                true);
-    }
-
-    /**
-     * {@icu} Returns a locale's language localized for display in the provided locale.
-     * If a dialect name is present in the data, then it is returned.
-     * This is a cover for the ICU4C API.
-     * @param localeID the id of the locale whose language will be displayed.
-     * @param displayLocale the locale in which to display the name.
-     * @return the localized language name.
-     * @stable ICU 4.4
-     */
-    public static String getDisplayLanguageWithDialect(String localeID, ULocale displayLocale) {
-        return getDisplayLanguageInternal(new ULocale(localeID), displayLocale, true);
-    }
-
-    private static String getDisplayLanguageInternal(ULocale locale, ULocale displayLocale,
-            boolean useDialect) {
-        //#com.ibm.icu.base
-        // No dialect support
-        return locale.toLocale().getDisplayLanguage(displayLocale.toLocale());
-    }
-
-    /**
-     * {@icu} Returns this locale's script localized for display in the default <code>DISPLAY</code> locale.
-     * @return the localized script name.
-     * @see Category#DISPLAY
-     * @stable ICU 3.0
-     */
-    public String getDisplayScript() {
-        return getDisplayScriptInternal(this, getDefault(Category.DISPLAY));
-    }
-
-    /**
-     * {@icu} Returns this locale's script localized for display in the provided locale.
-     * @param displayLocale the locale in which to display the name.
-     * @return the localized script name.
-     * @stable ICU 3.0
-     */
-    public String getDisplayScript(ULocale displayLocale) {
-        return getDisplayScriptInternal(this, displayLocale);
-    }
-
-    /**
-     * {@icu} Returns a locale's script localized for display in the provided locale.
-     * This is a cover for the ICU4C API.
-     * @param localeID the id of the locale whose script will be displayed
-     * @param displayLocaleID the id of the locale in which to display the name.
-     * @return the localized script name.
-     * @stable ICU 3.0
-     */
-    public static String getDisplayScript(String localeID, String displayLocaleID) {
-        return getDisplayScriptInternal(new ULocale(localeID), new ULocale(displayLocaleID));
-    }
-
-    /**
-     * {@icu} Returns a locale's script localized for display in the provided locale.
-     * @param localeID the id of the locale whose script will be displayed.
-     * @param displayLocale the locale in which to display the name.
-     * @return the localized script name.
-     * @stable ICU 3.0
-     */
-    public static String getDisplayScript(String localeID, ULocale displayLocale) {
-        return getDisplayScriptInternal(new ULocale(localeID), displayLocale);
-    }
-
-    // displayLocaleID is canonical, localeID need not be since parsing will fix this.
-    private static String getDisplayScriptInternal(ULocale locale, ULocale displayLocale) {
-        //#com.ibm.icu.base
-        String dispScript = null;
-        try {
-            // Calling Locale#getDisplayScript on Java 7 or later
-            Method mGetDisplayScript = Locale.class.getMethod("getDisplayScript", Locale.class);
-            dispScript = (String) mGetDisplayScript.invoke(locale.toLocale(), displayLocale.toLocale());
-            
-        } catch (NoSuchMethodException e) {
-        } catch (InvocationTargetException e) {
-        } catch (IllegalAccessException e) {
-        }
-
-        if (dispScript == null) {
-            dispScript = locale.getScript();
-        }
-        return dispScript;
-    }
-
-    /**
-     * Returns this locale's country localized for display in the default <code>DISPLAY</code> locale.
-     * @return the localized country name.
-     * @see Category#DISPLAY
-     * @stable ICU 3.0
-     */
-    public String getDisplayCountry() {
-        return getDisplayCountryInternal(this, getDefault(Category.DISPLAY));
-    }
-
-    /**
-     * Returns this locale's country localized for display in the provided locale.
-     * @param displayLocale the locale in which to display the name.
-     * @return the localized country name.
-     * @stable ICU 3.0
-     */
-    public String getDisplayCountry(ULocale displayLocale){
-        return getDisplayCountryInternal(this, displayLocale);
-    }
-
-    /**
-     * Returns a locale's country localized for display in the provided locale.
-     * This is a cover for the ICU4C API.
-     * @param localeID the id of the locale whose country will be displayed
-     * @param displayLocaleID the id of the locale in which to display the name.
-     * @return the localized country name.
-     * @stable ICU 3.0
-     */
-    public static String getDisplayCountry(String localeID, String displayLocaleID) {
-        return getDisplayCountryInternal(new ULocale(localeID), new ULocale(displayLocaleID));
-    }
-
-    /**
-     * Returns a locale's country localized for display in the provided locale.
-     * This is a cover for the ICU4C API.
-     * @param localeID the id of the locale whose country will be displayed.
-     * @param displayLocale the locale in which to display the name.
-     * @return the localized country name.
-     * @stable ICU 3.0
-     */
-    public static String getDisplayCountry(String localeID, ULocale displayLocale) {
-        return getDisplayCountryInternal(new ULocale(localeID), displayLocale);
-    }
-
-    // displayLocaleID is canonical, localeID need not be since parsing will fix this.
-    private static String getDisplayCountryInternal(ULocale locale, ULocale displayLocale) {
-        //#com.ibm.icu.base
-        return locale.toLocale().getDisplayCountry(displayLocale.toLocale());
-    }
-
-    /**
-     * Returns this locale's variant localized for display in the default <code>DISPLAY</code> locale.
-     * @return the localized variant name.
-     * @see Category#DISPLAY
-     * @stable ICU 3.0
-     */
-    public String getDisplayVariant() {
-        return getDisplayVariantInternal(this, getDefault(Category.DISPLAY));
-    }
-
-    /**
-     * Returns this locale's variant localized for display in the provided locale.
-     * @param displayLocale the locale in which to display the name.
-     * @return the localized variant name.
-     * @stable ICU 3.0
-     */
-    public String getDisplayVariant(ULocale displayLocale) {
-        return getDisplayVariantInternal(this, displayLocale);
-    }
-
-    /**
-     * Returns a locale's variant localized for display in the provided locale.
-     * This is a cover for the ICU4C API.
-     * @param localeID the id of the locale whose variant will be displayed
-     * @param displayLocaleID the id of the locale in which to display the name.
-     * @return the localized variant name.
-     * @stable ICU 3.0
-     */
-    public static String getDisplayVariant(String localeID, String displayLocaleID){
-        return getDisplayVariantInternal(new ULocale(localeID), new ULocale(displayLocaleID));
-    }
-
-    /**
-     * Returns a locale's variant localized for display in the provided locale.
-     * This is a cover for the ICU4C API.
-     * @param localeID the id of the locale whose variant will be displayed.
-     * @param displayLocale the locale in which to display the name.
-     * @return the localized variant name.
-     * @stable ICU 3.0
-     */
-    public static String getDisplayVariant(String localeID, ULocale displayLocale) {
-        return getDisplayVariantInternal(new ULocale(localeID), displayLocale);
-    }
-
-    private static String getDisplayVariantInternal(ULocale locale, ULocale displayLocale) {
-        //#com.ibm.icu.base
-        return locale.toLocale().getDisplayVariant(displayLocale.toLocale());
-    }
-
-    /**
-     * {@icu} Returns a keyword localized for display in the default <code>DISPLAY</code> locale.
-     * @param keyword the keyword to be displayed.
-     * @return the localized keyword name.
-     * @see #getKeywords()
-     * @see Category#DISPLAY
-     * @stable ICU 3.0
-     */
-    public static String getDisplayKeyword(String keyword) {
-        return getDisplayKeywordInternal(keyword, getDefault(Category.DISPLAY));
-    }
-
-    /**
-     * {@icu} Returns a keyword localized for display in the specified locale.
-     * @param keyword the keyword to be displayed.
-     * @param displayLocaleID the id of the locale in which to display the keyword.
-     * @return the localized keyword name.
-     * @see #getKeywords(String)
-     * @stable ICU 3.0
-     */
-    public static String getDisplayKeyword(String keyword, String displayLocaleID) {
-        return getDisplayKeywordInternal(keyword, new ULocale(displayLocaleID));
-    }
-
-    /**
-     * {@icu} Returns a keyword localized for display in the specified locale.
-     * @param keyword the keyword to be displayed.
-     * @param displayLocale the locale in which to display the keyword.
-     * @return the localized keyword name.
-     * @see #getKeywords(String)
-     * @stable ICU 3.0
-     */
-    public static String getDisplayKeyword(String keyword, ULocale displayLocale) {
-        return getDisplayKeywordInternal(keyword, displayLocale);
-    }
-
-    private static String getDisplayKeywordInternal(String keyword, ULocale displayLocale) {
-        //#com.ibm.icu.base
-        // No localization
-        return keyword;
-    }
-
-    /**
-     * {@icu} Returns a keyword value localized for display in the default <code>DISPLAY</code> locale.
-     * @param keyword the keyword whose value is to be displayed.
-     * @return the localized value name.
-     * @see Category#DISPLAY
-     * @stable ICU 3.0
-     */
-    public String getDisplayKeywordValue(String keyword) {
-        return getDisplayKeywordValueInternal(this, keyword, getDefault(Category.DISPLAY));
-    }
-
-    /**
-     * {@icu} Returns a keyword value localized for display in the specified locale.
-     * @param keyword the keyword whose value is to be displayed.
-     * @param displayLocale the locale in which to display the value.
-     * @return the localized value name.
-     * @stable ICU 3.0
-     */
-    public String getDisplayKeywordValue(String keyword, ULocale displayLocale) {
-        return getDisplayKeywordValueInternal(this, keyword, displayLocale);
-    }
-
-    /**
-     * {@icu} Returns a keyword value localized for display in the specified locale.
-     * This is a cover for the ICU4C API.
-     * @param localeID the id of the locale whose keyword value is to be displayed.
-     * @param keyword the keyword whose value is to be displayed.
-     * @param displayLocaleID the id of the locale in which to display the value.
-     * @return the localized value name.
-     * @stable ICU 3.0
-     */
-    public static String getDisplayKeywordValue(String localeID, String keyword,
-            String displayLocaleID) {
-        return getDisplayKeywordValueInternal(new ULocale(localeID), keyword,
-                new ULocale(displayLocaleID));
-    }
-
-    /**
-     * {@icu} Returns a keyword value localized for display in the specified locale.
-     * This is a cover for the ICU4C API.
-     * @param localeID the id of the locale whose keyword value is to be displayed.
-     * @param keyword the keyword whose value is to be displayed.
-     * @param displayLocale the id of the locale in which to display the value.
-     * @return the localized value name.
-     * @stable ICU 3.0
-     */
-    public static String getDisplayKeywordValue(String localeID, String keyword,
-            ULocale displayLocale) {
-        return getDisplayKeywordValueInternal(new ULocale(localeID), keyword, displayLocale);
-    }
-
-    // displayLocaleID is canonical, localeID need not be since parsing will fix this.
-    private static String getDisplayKeywordValueInternal(ULocale locale, String keyword,
-            ULocale displayLocale) {
-        //#com.ibm.icu.base
-        keyword = AsciiUtil.toLowerString(keyword.trim());
-        String value = locale.getKeywordValue(keyword);
-        // No localization
-        return value;
-    }
-
-    /**
-     * Returns this locale name localized for display in the default <code>DISPLAY</code> locale.
-     * @return the localized locale name.
-     * @see Category#DISPLAY
-     * @stable ICU 3.0
-     */
-    public String getDisplayName() {
-        return getDisplayNameInternal(this, getDefault(Category.DISPLAY));
-    }
-
-    /**
-     * Returns this locale name localized for display in the provided locale.
-     * @param displayLocale the locale in which to display the locale name.
-     * @return the localized locale name.
-     * @stable ICU 3.0
-     */
-    public String getDisplayName(ULocale displayLocale) {
-        return getDisplayNameInternal(this, displayLocale);
-    }
-
-    /**
-     * Returns the locale ID localized for display in the provided locale.
-     * This is a cover for the ICU4C API.
-     * @param localeID the locale whose name is to be displayed.
-     * @param displayLocaleID the id of the locale in which to display the locale name.
-     * @return the localized locale name.
-     * @stable ICU 3.0
-     */
-    public static String getDisplayName(String localeID, String displayLocaleID) {
-        return getDisplayNameInternal(new ULocale(localeID), new ULocale(displayLocaleID));
-    }
-
-    /**
-     * Returns the locale ID localized for display in the provided locale.
-     * This is a cover for the ICU4C API.
-     * @param localeID the locale whose name is to be displayed.
-     * @param displayLocale the locale in which to display the locale name.
-     * @return the localized locale name.
-     * @stable ICU 3.0
-     */
-    public static String getDisplayName(String localeID, ULocale displayLocale) {
-        return getDisplayNameInternal(new ULocale(localeID), displayLocale);
-    }
-
-    private static String getDisplayNameInternal(ULocale locale, ULocale displayLocale) {
-        //#com.ibm.icu.base
-        return locale.toLocale().getDisplayName(displayLocale.toLocale());
-    }
-
-    /**
-     * {@icu} Returns this locale name localized for display in the default <code>DISPLAY</code> locale.
-     * If a dialect name is present in the locale data, then it is returned.
-     * @return the localized locale name.
-     * @see Category#DISPLAY
-     * @stable ICU 4.4
-     */
-    public String getDisplayNameWithDialect() {
-        return getDisplayNameWithDialectInternal(this, getDefault(Category.DISPLAY));
-    }
-
-    /**
-     * {@icu} Returns this locale name localized for display in the provided locale.
-     * If a dialect name is present in the locale data, then it is returned.
-     * @param displayLocale the locale in which to display the locale name.
-     * @return the localized locale name.
-     * @stable ICU 4.4
-     */
-    public String getDisplayNameWithDialect(ULocale displayLocale) {
-        return getDisplayNameWithDialectInternal(this, displayLocale);
-    }
-
-    /**
-     * {@icu} Returns the locale ID localized for display in the provided locale.
-     * If a dialect name is present in the locale data, then it is returned.
-     * This is a cover for the ICU4C API.
-     * @param localeID the locale whose name is to be displayed.
-     * @param displayLocaleID the id of the locale in which to display the locale name.
-     * @return the localized locale name.
-     * @stable ICU 4.4
-     */
-    public static String getDisplayNameWithDialect(String localeID, String displayLocaleID) {
-        return getDisplayNameWithDialectInternal(new ULocale(localeID),
-                new ULocale(displayLocaleID));
-    }
-
-    /**
-     * {@icu} Returns the locale ID localized for display in the provided locale.
-     * If a dialect name is present in the locale data, then it is returned.
-     * This is a cover for the ICU4C API.
-     * @param localeID the locale whose name is to be displayed.
-     * @param displayLocale the locale in which to display the locale name.
-     * @return the localized locale name.
-     * @stable ICU 4.4
-     */
-    public static String getDisplayNameWithDialect(String localeID, ULocale displayLocale) {
-        return getDisplayNameWithDialectInternal(new ULocale(localeID), displayLocale);
-    }
-
-    private static String getDisplayNameWithDialectInternal(ULocale locale, ULocale displayLocale) {
-        //#com.ibm.icu.base
-        // No dialect handling
-        return locale.toLocale().getDisplayName(displayLocale.toLocale());
-    }
-
-    /**
-     * {@icu} Returns this locale's layout orientation for characters.  The possible
-     * values are "left-to-right", "right-to-left", "top-to-bottom" or
-     * "bottom-to-top".
-     * @return The locale's layout orientation for characters.
-     * @stable ICU 4.0
-     */
-    public String getCharacterOrientation() {
-        //#com.ibm.icu.base
-        // Hardcoded
-        String lang = getLanguage();
-        if (lang.equals("ar") || lang.equals("fa") || lang.equals("he") || lang.equals("ps") || lang.equals("ur")) {
-            return "right-to-left";
-        }
-        String script = getScript();
-        if (script.equals("Arab")) {
-            return "right-to-left";
-        }
-        return "left-to-right";
-    }
-
-    /**
-     * {@icu} Returns this locale's layout orientation for lines.  The possible
-     * values are "left-to-right", "right-to-left", "top-to-bottom" or
-     * "bottom-to-top".
-     * @return The locale's layout orientation for lines.
-     * @stable ICU 4.0
-     */
-    public String getLineOrientation() {
-        //#com.ibm.icu.base
-        return "top-to-bottom";
-    }
-
-    /**
-     * {@icu} Selector for <tt>getLocale()</tt> indicating the locale of the
-     * resource containing the data.  This is always at or above the
-     * valid locale.  If the valid locale does not contain the
-     * specific data being requested, then the actual locale will be
-     * above the valid locale.  If the object was not constructed from
-     * locale data, then the valid locale is <i>null</i>.
-     *
-     * @draft ICU 2.8 (retain)
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static Type ACTUAL_LOCALE = new Type();
-
-    /**
-     * {@icu} Selector for <tt>getLocale()</tt> indicating the most specific
-     * locale for which any data exists.  This is always at or above
-     * the requested locale, and at or below the actual locale.  If
-     * the requested locale does not correspond to any resource data,
-     * then the valid locale will be above the requested locale.  If
-     * the object was not constructed from locale data, then the
-     * actual locale is <i>null</i>.
-     *
-     * <p>Note: The valid locale will be returned correctly in ICU
-     * 3.0 or later.  In ICU 2.8, it is not returned correctly.
-     * @draft ICU 2.8 (retain)
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static Type VALID_LOCALE = new Type();
-
-    /**
-     * Opaque selector enum for <tt>getLocale()</tt>.
-     * @see com.ibm.icu.util.ULocale
-     * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
-     * @see com.ibm.icu.util.ULocale#VALID_LOCALE
-     * @draft ICU 2.8 (retainAll)
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final class Type {
-        private Type() {}
-    }
-
-  /**
-    * {@icu} Based on a HTTP formatted list of acceptable locales, determine an available
-    * locale for the user.  NullPointerException is thrown if acceptLanguageList or
-    * availableLocales is null.  If fallback is non-null, it will contain true if a
-    * fallback locale (one not in the acceptLanguageList) was returned.  The value on
-    * entry is ignored.  ULocale will be one of the locales in availableLocales, or the
-    * ROOT ULocale if if a ROOT locale was used as a fallback (because nothing else in
-    * availableLocales matched).  No ULocale array element should be null; behavior is
-    * undefined if this is the case.
-    * @param acceptLanguageList list in HTTP "Accept-Language:" format of acceptable locales
-    * @param availableLocales list of available locales. One of these will be returned.
-    * @param fallback if non-null, a 1-element array containing a boolean to be set with
-    * the fallback status
-    * @return one of the locales from the availableLocales list, or null if none match
-    * @stable ICU 3.4
-    */
-    public static ULocale acceptLanguage(String acceptLanguageList, ULocale[] availableLocales,
-                                         boolean[] fallback) {
-        if (acceptLanguageList == null) {
-            throw new NullPointerException();
-        }
-        ULocale acceptList[] = null;
-        try {
-            acceptList = parseAcceptLanguage(acceptLanguageList, true);
-        } catch (ParseException pe) {
-            acceptList = null;
-        }
-        if (acceptList == null) {
-            return null;
-        }
-        return acceptLanguage(acceptList, availableLocales, fallback);
-    }
-
-    /**
-    * {@icu} Based on a list of acceptable locales, determine an available locale for the
-    * user.  NullPointerException is thrown if acceptLanguageList or availableLocales is
-    * null.  If fallback is non-null, it will contain true if a fallback locale (one not
-    * in the acceptLanguageList) was returned.  The value on entry is ignored.  ULocale
-    * will be one of the locales in availableLocales, or the ROOT ULocale if if a ROOT
-    * locale was used as a fallback (because nothing else in availableLocales matched).
-    * No ULocale array element should be null; behavior is undefined if this is the case.
-    * @param acceptLanguageList list of acceptable locales
-    * @param availableLocales list of available locales. One of these will be returned.
-    * @param fallback if non-null, a 1-element array containing a boolean to be set with
-    * the fallback status
-    * @return one of the locales from the availableLocales list, or null if none match
-    * @stable ICU 3.4
-    */
-
-    public static ULocale acceptLanguage(ULocale[] acceptLanguageList, ULocale[]
-    availableLocales, boolean[] fallback) {
-        // fallbacklist
-        int i,j;
-        if(fallback != null) {
-            fallback[0]=true;
-        }
-        for(i=0;i<acceptLanguageList.length;i++) {
-            ULocale aLocale = acceptLanguageList[i];
-            boolean[] setFallback = fallback;
-            do {
-                for(j=0;j<availableLocales.length;j++) {
-                    if(availableLocales[j].equals(aLocale)) {
-                        if(setFallback != null) {
-                            setFallback[0]=false; // first time with this locale - not a fallback.
-                        }
-                        return availableLocales[j];
-                    }
-                    // compare to scriptless alias, so locales such as
-                    // zh_TW, zh_CN are considered as available locales - see #7190
-                    if (aLocale.getScript().length() == 0
-                            && availableLocales[j].getScript().length() > 0
-                            && availableLocales[j].getLanguage().equals(aLocale.getLanguage())
-                            && availableLocales[j].getCountry().equals(aLocale.getCountry())
-                            && availableLocales[j].getVariant().equals(aLocale.getVariant())) {
-                        ULocale minAvail = ULocale.minimizeSubtags(availableLocales[j]);
-                        if (minAvail.getScript().length() == 0) {
-                            if(setFallback != null) {
-                                setFallback[0] = false; // not a fallback.
-                            }
-                            return aLocale;
-                        }
-                    }
-                }
-                Locale loc = aLocale.toLocale();
-                Locale parent = LocaleUtility.fallback(loc);
-                if(parent != null) {
-                    aLocale = new ULocale(parent);
-                } else {
-                    aLocale = null;
-                }
-                setFallback = null; // Do not set fallback in later iterations
-            } while (aLocale != null);
-        }
-        return null;
-    }
-
-   /**
-    * {@icu} Based on a HTTP formatted list of acceptable locales, determine an available
-    * locale for the user.  NullPointerException is thrown if acceptLanguageList or
-    * availableLocales is null.  If fallback is non-null, it will contain true if a
-    * fallback locale (one not in the acceptLanguageList) was returned.  The value on
-    * entry is ignored.  ULocale will be one of the locales in availableLocales, or the
-    * ROOT ULocale if if a ROOT locale was used as a fallback (because nothing else in
-    * availableLocales matched).  No ULocale array element should be null; behavior is
-    * undefined if this is the case.  This function will choose a locale from the
-    * ULocale.getAvailableLocales() list as available.
-    * @param acceptLanguageList list in HTTP "Accept-Language:" format of acceptable locales
-    * @param fallback if non-null, a 1-element array containing a boolean to be set with
-    * the fallback status
-    * @return one of the locales from the ULocale.getAvailableLocales() list, or null if
-    * none match
-    * @stable ICU 3.4
-    */
-    public static ULocale acceptLanguage(String acceptLanguageList, boolean[] fallback) {
-        return acceptLanguage(acceptLanguageList, ULocale.getAvailableLocales(),
-                                fallback);
-    }
-
-   /**
-    * {@icu} Based on an ordered array of acceptable locales, determine an available
-    * locale for the user.  NullPointerException is thrown if acceptLanguageList or
-    * availableLocales is null.  If fallback is non-null, it will contain true if a
-    * fallback locale (one not in the acceptLanguageList) was returned.  The value on
-    * entry is ignored.  ULocale will be one of the locales in availableLocales, or the
-    * ROOT ULocale if if a ROOT locale was used as a fallback (because nothing else in
-    * availableLocales matched).  No ULocale array element should be null; behavior is
-    * undefined if this is the case.  This function will choose a locale from the
-    * ULocale.getAvailableLocales() list as available.
-    * @param acceptLanguageList ordered array of acceptable locales (preferred are listed first)
-    * @param fallback if non-null, a 1-element array containing a boolean to be set with
-    * the fallback status
-    * @return one of the locales from the ULocale.getAvailableLocales() list, or null if none match
-    * @stable ICU 3.4
-    */
-    public static ULocale acceptLanguage(ULocale[] acceptLanguageList, boolean[] fallback) {
-        return acceptLanguage(acceptLanguageList, ULocale.getAvailableLocales(),
-                fallback);
-    }
-
-    /**
-     * Package local method used for parsing Accept-Language string
-     */
-    static ULocale[] parseAcceptLanguage(String acceptLanguage, boolean isLenient) 
-        throws ParseException {
-        class ULocaleAcceptLanguageQ implements Comparable<ULocaleAcceptLanguageQ> {
-            private double q;
-            private double serial;
-            public ULocaleAcceptLanguageQ(double theq, int theserial) {
-                q = theq;
-                serial = theserial;
-            }
-            public int compareTo(ULocaleAcceptLanguageQ other) {
-                if (q > other.q) { // reverse - to sort in descending order
-                    return -1;
-                } else if (q < other.q) {
-                    return 1;
-                }
-                if (serial < other.serial) {
-                    return -1;
-                } else if (serial > other.serial) {
-                    return 1;
-                } else {
-                    return 0; // same object
-                }
-            }
-        }
-
-        // parse out the acceptLanguage into an array
-        TreeMap<ULocaleAcceptLanguageQ, ULocale> map = 
-            new TreeMap<ULocaleAcceptLanguageQ, ULocale>();
-        StringBuilder languageRangeBuf = new StringBuilder();
-        StringBuilder qvalBuf = new StringBuilder();
-        int state = 0;
-        acceptLanguage += ","; // append comma to simplify the parsing code
-        int n;
-        boolean subTag = false;
-        boolean q1 = false;
-        for (n = 0; n < acceptLanguage.length(); n++) {
-            boolean gotLanguageQ = false;
-            char c = acceptLanguage.charAt(n);
-            switch (state) {
-            case 0: // before language-range start
-                if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) {
-                    // in language-range
-                    languageRangeBuf.append(c);
-                    state = 1;
-                    subTag = false;
-                } else if (c == '*') {
-                    languageRangeBuf.append(c);
-                    state = 2;
-                } else if (c != ' ' && c != '\t') {
-                    // invalid character
-                    state = -1;
-                }
-                break;
-            case 1: // in language-range
-                if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) {
-                    languageRangeBuf.append(c);
-                } else if (c == '-') {
-                    subTag = true;
-                    languageRangeBuf.append(c);
-                } else if (c == '_') {
-                    if (isLenient) {
-                        subTag = true;
-                        languageRangeBuf.append(c);
-                    } else {
-                        state = -1;
-                    }
-                } else if ('0' <= c && c <= '9') {
-                    if (subTag) {
-                        languageRangeBuf.append(c);
-                    } else {
-                        // DIGIT is allowed only in language sub tag
-                        state = -1;
-                    }
-                } else if (c == ',') {
-                    // language-q end
-                    gotLanguageQ = true;
-                } else if (c == ' ' || c == '\t') {
-                    // language-range end
-                    state = 3;
-                } else if (c == ';') {
-                    // before q
-                    state = 4;
-                } else {
-                    // invalid character for language-range
-                    state = -1;
-                }
-                break;
-            case 2: // saw wild card range
-                if (c == ',') {
-                    // language-q end
-                    gotLanguageQ = true;
-                } else if (c == ' ' || c == '\t') {
-                    // language-range end
-                    state = 3;
-                } else if (c == ';') {
-                    // before q
-                    state = 4;
-                } else {
-                    // invalid
-                    state = -1;
-                }
-                break;
-            case 3: // language-range end
-                if (c == ',') {
-                    // language-q end
-                    gotLanguageQ = true;
-                } else if (c == ';') {
-                    // before q
-                    state =4;
-                } else if (c != ' ' && c != '\t') {
-                    // invalid
-                    state = -1;
-                }
-                break;
-            case 4: // before q
-                if (c == 'q') {
-                    // before equal
-                    state = 5;
-                } else if (c != ' ' && c != '\t') {
-                    // invalid
-                    state = -1;
-                }
-                break;
-            case 5: // before equal
-                if (c == '=') {
-                    // before q value
-                    state = 6;
-                } else if (c != ' ' && c != '\t') {
-                    // invalid
-                    state = -1;
-                }
-                break;
-            case 6: // before q value
-                if (c == '0') {
-                    // q value start with 0
-                    q1 = false;
-                    qvalBuf.append(c);
-                    state = 7;
-                } else if (c == '1') {
-                    // q value start with 1
-                    qvalBuf.append(c);
-                    state = 7;
-                } else if (c == '.') {
-                    if (isLenient) {
-                        qvalBuf.append(c);
-                        state = 8;
-                    } else {
-                        state = -1;
-                    }
-                } else if (c != ' ' && c != '\t') {
-                    // invalid
-                    state = -1;
-                }
-                break;
-            case 7: // q value start
-                if (c == '.') {
-                    // before q value fraction part
-                    qvalBuf.append(c);
-                    state = 8;
-                } else if (c == ',') {
-                    // language-q end
-                    gotLanguageQ = true;
-                } else if (c == ' ' || c == '\t') {
-                    // after q value
-                    state = 10;
-                } else {
-                    // invalid
-                    state = -1;
-                }
-                break;
-            case 8: // before q value fraction part
-                if ('0' <= c || c <= '9') {
-                    if (q1 && c != '0' && !isLenient) {
-                        // if q value starts with 1, the fraction part must be 0
-                        state = -1;
-                    } else {
-                        // in q value fraction part
-                        qvalBuf.append(c);
-                        state = 9;
-                    }
-                } else {
-                    // invalid
-                    state = -1;
-                }
-                break;
-            case 9: // in q value fraction part
-                if ('0' <= c && c <= '9') {
-                    if (q1 && c != '0') {
-                        // if q value starts with 1, the fraction part must be 0
-                        state = -1;
-                    } else {
-                        qvalBuf.append(c);
-                    }
-                } else if (c == ',') {
-                    // language-q end
-                    gotLanguageQ = true;
-                } else if (c == ' ' || c == '\t') {
-                    // after q value
-                    state = 10;
-                } else {
-                    // invalid
-                    state = -1;
-                }
-                break;
-            case 10: // after q value
-                if (c == ',') {
-                    // language-q end
-                    gotLanguageQ = true;
-                } else if (c != ' ' && c != '\t') {
-                    // invalid
-                    state = -1;
-                }
-                break;
-            }
-            if (state == -1) {
-                // error state
-                throw new ParseException("Invalid Accept-Language", n);
-            }
-            if (gotLanguageQ) {
-                double q = 1.0;
-                if (qvalBuf.length() != 0) {
-                    try {
-                        q = Double.parseDouble(qvalBuf.toString());
-                    } catch (NumberFormatException nfe) {
-                        // Already validated, so it should never happen
-                        q = 1.0;
-                    }
-                    if (q > 1.0) {
-                        q = 1.0;
-                    }
-                }
-                if (languageRangeBuf.charAt(0) != '*') {
-                    int serial = map.size();
-                    ULocaleAcceptLanguageQ entry = new ULocaleAcceptLanguageQ(q, serial);
-                    // sort in reverse order..   1.0, 0.9, 0.8 .. etc
-                    map.put(entry, new ULocale(canonicalize(languageRangeBuf.toString())));
-                }
-
-                // reset buffer and parse state
-                languageRangeBuf.setLength(0);
-                qvalBuf.setLength(0);
-                state = 0;
-            }
-        }
-        if (state != 0) {
-            // Well, the parser should handle all cases.  So just in case.
-            throw new ParseException("Invalid AcceptlLanguage", n);
-        }
-
-        // pull out the map
-        ULocale acceptList[] = map.values().toArray(new ULocale[map.size()]);
-        return acceptList;
-    }
-
-    private static final String UNDEFINED_LANGUAGE = "und";
-
-    /**
-     * {@icu} Adds the likely subtags for a provided locale ID, per the algorithm
-     * described in the following CLDR technical report:
-     *
-     *   http://www.unicode.org/reports/tr35/#Likely_Subtags
-     *
-     * If the provided ULocale instance is already in the maximal form, or there is no
-     * data available available for maximization, it will be returned.  For example,
-     * "und-Zzzz" cannot be maximized, since there is no reasonable maximization.
-     * Otherwise, a new ULocale instance with the maximal form is returned.
-     *
-     * Examples:
-     *
-     * "en" maximizes to "en_Latn_US"
-     *
-     * "de" maximizes to "de_Latn_US"
-     *
-     * "sr" maximizes to "sr_Cyrl_RS"
-     *
-     * "sh" maximizes to "sr_Latn_RS" (Note this will not reverse.)
-     *
-     * "zh_Hani" maximizes to "zh_Hans_CN" (Note this will not reverse.)
-     *
-     * @param loc The ULocale to maximize
-     * @return The maximized ULocale instance.
-     * @stable ICU 4.0
-     */
-    public static ULocale addLikelySubtags(ULocale loc) {
-        //#com.ibm.icu.base
-        return loc;
-    }
-
-    /**
-     * {@icu} Minimizes the subtags for a provided locale ID, per the algorithm described
-     * in the following CLDR technical report:<blockquote>
-     *
-     *   <a href="http://www.unicode.org/reports/tr35/#Likely_Subtags"
-     *>http://www.unicode.org/reports/tr35/#Likely_Subtags</a></blockquote>
-     *
-     * If the provided ULocale instance is already in the minimal form, or there
-     * is no data available for minimization, it will be returned.  Since the
-     * minimization algorithm relies on proper maximization, see the comments
-     * for addLikelySubtags for reasons why there might not be any data.
-     *
-     * Examples:<pre>
-     *
-     * "en_Latn_US" minimizes to "en"
-     *
-     * "de_Latn_US" minimizes to "de"
-     *
-     * "sr_Cyrl_RS" minimizes to "sr"
-     *
-     * "zh_Hant_TW" minimizes to "zh_TW" (The region is preferred to the
-     * script, and minimizing to "zh" would imply "zh_Hans_CN".) </pre>
-     *
-     * @param loc The ULocale to minimize
-     * @return The minimized ULocale instance.
-     * @stable ICU 4.0
-     */
-    public static ULocale minimizeSubtags(ULocale loc) {
-        //#com.ibm.icu.base
-        return loc;
-    }
-
-    /**
-     * A trivial utility function that checks for a null
-     * reference or checks the length of the supplied String.
-     *
-     *   @param string The string to check
-     *
-     *   @return true if the String is empty, or if the reference is null.
-     */
-    private static boolean isEmptyString(String string) {
-      return string == null || string.length() == 0;
-    }
-
-    /**
-     * Append a tag to a StringBuilder, adding the separator if necessary.The tag must
-     * not be a zero-length string.
-     *
-     * @param tag The tag to add.
-     * @param buffer The output buffer.
-     **/
-    private static void appendTag(String tag, StringBuilder buffer) {
-        if (buffer.length() != 0) {
-            buffer.append(UNDERSCORE);
-        }
-
-        buffer.append(tag);
-    }
-
-    /**
-     * Create a tag string from the supplied parameters.  The lang, script and region
-     * parameters may be null references.
-     *
-     * If any of the language, script or region parameters are empty, and the alternateTags
-     * parameter is not null, it will be parsed for potential language, script and region tags
-     * to be used when constructing the new tag.  If the alternateTags parameter is null, or
-     * it contains no language tag, the default tag for the unknown language is used.
-     *
-     * @param lang The language tag to use.
-     * @param script The script tag to use.
-     * @param region The region tag to use.
-     * @param trailing Any trailing data to append to the new tag.
-     * @param alternateTags A string containing any alternate tags.
-     * @return The new tag string.
-     **/
-    private static String createTagString(String lang, String script, String region,
-        String trailing, String alternateTags) {
-
-        LocaleIDParser parser = null;
-        boolean regionAppended = false;
-
-        StringBuilder tag = new StringBuilder();
-
-        if (!isEmptyString(lang)) {
-            appendTag(
-                lang,
-                tag);
-        }
-        else if (isEmptyString(alternateTags)) {
-            /*
-             * Append the value for an unknown language, if
-             * we found no language.
-             */
-            appendTag(
-                UNDEFINED_LANGUAGE,
-                tag);
-        }
-        else {
-            parser = new LocaleIDParser(alternateTags);
-
-            String alternateLang = parser.getLanguage();
-
-            /*
-             * Append the value for an unknown language, if
-             * we found no language.
-             */
-            appendTag(
-                !isEmptyString(alternateLang) ? alternateLang : UNDEFINED_LANGUAGE,
-                tag);
-        }
-
-        if (!isEmptyString(script)) {
-            appendTag(
-                script,
-                tag);
-        }
-        else if (!isEmptyString(alternateTags)) {
-            /*
-             * Parse the alternateTags string for the script.
-             */
-            if (parser == null) {
-                parser = new LocaleIDParser(alternateTags);
-            }
-
-            String alternateScript = parser.getScript();
-
-            if (!isEmptyString(alternateScript)) {
-                appendTag(
-                    alternateScript,
-                    tag);
-            }
-        }
-
-        if (!isEmptyString(region)) {
-            appendTag(
-                region,
-                tag);
-
-            regionAppended = true;
-        }
-        else if (!isEmptyString(alternateTags)) {
-            /*
-             * Parse the alternateTags string for the region.
-             */
-            if (parser == null) {
-                parser = new LocaleIDParser(alternateTags);
-            }
-
-            String alternateRegion = parser.getCountry();
-
-            if (!isEmptyString(alternateRegion)) {
-                appendTag(
-                    alternateRegion,
-                    tag);
-
-                regionAppended = true;
-            }
-        }
-
-        if (trailing != null && trailing.length() > 1) {
-            /*
-             * The current ICU format expects two underscores
-             * will separate the variant from the preceeding
-             * parts of the tag, if there is no region.
-             */
-            int separators = 0;
-
-            if (trailing.charAt(0) == UNDERSCORE) {
-                if (trailing.charAt(1) == UNDERSCORE) {
-                    separators = 2;
-                }
-                }
-                else {
-                    separators = 1;
-                }
-
-            if (regionAppended) {
-                /*
-                 * If we appended a region, we may need to strip
-                 * the extra separator from the variant portion.
-                 */
-                if (separators == 2) {
-                    tag.append(trailing.substring(1));
-                }
-                else {
-                    tag.append(trailing);
-                }
-            }
-            else {
-                /*
-                 * If we did not append a region, we may need to add
-                 * an extra separator to the variant portion.
-                 */
-                if (separators == 1) {
-                    tag.append(UNDERSCORE);
-                }
-                tag.append(trailing);
-            }
-        }
-
-        return tag.toString();
-    }
-
-    /**
-     * Create a tag string from the supplied parameters.  The lang, script and region
-     * parameters may be null references.If the lang parameter is an empty string, the
-     * default value for an unknown language is written to the output buffer.
-     *
-     * @param lang The language tag to use.
-     * @param script The script tag to use.
-     * @param region The region tag to use.
-     * @param trailing Any trailing data to append to the new tag.
-     * @return The new String.
-     **/
-    static String createTagString(String lang, String script, String region, String trailing) {
-        return createTagString(lang, script, region, trailing, null);
-    }
-
-    // --------------------------------
-    //      BCP47/OpenJDK APIs
-    // --------------------------------
-
-    /**
-     * {@icu} The key for the private use locale extension ('x').
-     *
-     * @see #getExtension(char)
-     * @see Builder#setExtension(char, String)
-     *
-     * @draft ICU 4.2
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final char PRIVATE_USE_EXTENSION = 'x';
-
-    /**
-     * {@icu} The key for Unicode locale extension ('u').
-     *
-     * @see #getExtension(char)
-     * @see Builder#setExtension(char, String)
-     *
-     * @draft ICU 4.2
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final char UNICODE_LOCALE_EXTENSION = 'u';
-
-    /**
-     * {@icu} Returns the extension (or private use) value associated with
-     * the specified key, or null if there is no extension
-     * associated with the key. To be well-formed, the key must be one
-     * of <code>[0-9A-Za-z]</code>. Keys are case-insensitive, so
-     * for example 'z' and 'Z' represent the same extension.
-     *
-     * @param key the extension key
-     * @return The extension, or null if this locale defines no
-     * extension for the specified key.
-     * @throws IllegalArgumentException if key is not well-formed
-     * @see #PRIVATE_USE_EXTENSION
-     * @see #UNICODE_LOCALE_EXTENSION
-     *
-     * @draft ICU 4.2
-     * @provisional This API might change or be removed in a future release.
-     */
-    public String getExtension(char key) {
-        if (!LocaleExtensions.isValidKey(key)) {
-            throw new IllegalArgumentException("Invalid extension key: " + key);
-        }
-        return extensions().getExtensionValue(key);
-    }
-
-    /**
-     * {@icu} Returns the set of extension keys associated with this locale, or the
-     * empty set if it has no extensions. The returned set is unmodifiable.
-     * The keys will all be lower-case.
-     *
-     * @return the set of extension keys, or the empty set if this locale has
-     * no extensions
-     * @draft ICU 4.2
-     * @provisional This API might change or be removed in a future release.
-     */
-    public Set<Character> getExtensionKeys() {
-        return extensions().getKeys();
-    }
-
-    /**
-     * {@icu} Returns the set of unicode locale attributes associated with
-     * this locale, or the empty set if it has no attributes. The
-     * returned set is unmodifiable.
-     *
-     * @return The set of attributes.
-     * @draft ICU 4.6
-     * @provisional This API might change or be removed in a future release.
-     */
-    public Set<String> getUnicodeLocaleAttributes() {
-        return extensions().getUnicodeLocaleAttributes();
-    }
-
-    /**
-     * {@icu} Returns the Unicode locale type associated with the specified Unicode locale key
-     * for this locale. Returns the empty string for keys that are defined with no type.
-     * Returns null if the key is not defined. Keys are case-insensitive. The key must
-     * be two alphanumeric characters ([0-9a-zA-Z]), or an IllegalArgumentException is
-     * thrown.
-     *
-     * @param key the Unicode locale key
-     * @return The Unicode locale type associated with the key, or null if the
-     * locale does not define the key.
-     * @throws IllegalArgumentException if the key is not well-formed
-     * @throws NullPointerException if <code>key</code> is null
-     * 
-     * @draft ICU 4.4
-     * @provisional This API might change or be removed in a future release.
-     */
-    public String getUnicodeLocaleType(String key) {
-        if (!LocaleExtensions.isValidUnicodeLocaleKey(key)) {
-            throw new IllegalArgumentException("Invalid Unicode locale key: " + key);
-        }
-        return extensions().getUnicodeLocaleType(key);
-    }
-
-    /**
-     * {@icu} Returns the set of Unicode locale keys defined by this locale, or the empty set if
-     * this locale has none.  The returned set is immutable.  Keys are all lower case.
-     *
-     * @return The set of Unicode locale keys, or the empty set if this locale has
-     * no Unicode locale keywords.
-     * 
-     * @draft ICU 4.4
-     * @provisional This API might change or be removed in a future release.
-     */
-    public Set<String> getUnicodeLocaleKeys() {
-        return extensions().getUnicodeLocaleKeys();
-    }
-
-    /**
-     * {@icu} Returns a well-formed IETF BCP 47 language tag representing
-     * this locale.
-     *
-     * <p>If this <code>ULocale</code> has a language, script, country, or
-     * variant that does not satisfy the IETF BCP 47 language tag
-     * syntax requirements, this method handles these fields as
-     * described below:
-     *
-     * <p><b>Language:</b> If language is empty, or not well-formed
-     * (for example "a" or "e2"), it will be emitted as "und" (Undetermined).
-     *
-     * <p><b>Script:</b> If script is not well-formed (for example "12"
-     * or "Latin"), it will be omitted.
-     * 
-     * <p><b>Country:</b> If country is not well-formed (for example "12"
-     * or "USA"), it will be omitted.
-     *
-     * <p><b>Variant:</b> If variant <b>is</b> well-formed, each sub-segment
-     * (delimited by '-' or '_') is emitted as a subtag.  Otherwise:
-     * <ul>
-     *
-     * <li>if all sub-segments match <code>[0-9a-zA-Z]{1,8}</code>
-     * (for example "WIN" or "Oracle_JDK_Standard_Edition"), the first
-     * ill-formed sub-segment and all following will be appended to
-     * the private use subtag.  The first appended subtag will be
-     * "lvariant", followed by the sub-segments in order, separated by
-     * hyphen. For example, "x-lvariant-WIN",
-     * "Oracle-x-lvariant-JDK-Standard-Edition".
-     *
-     * <li>if any sub-segment does not match
-     * <code>[0-9a-zA-Z]{1,8}</code>, the variant will be truncated
-     * and the problematic sub-segment and all following sub-segments
-     * will be omitted.  If the remainder is non-empty, it will be
-     * emitted as a private use subtag as above (even if the remainder
-     * turns out to be well-formed).  For example,
-     * "Solaris_isjustthecoolestthing" is emitted as
-     * "x-lvariant-Solaris", not as "solaris".</li></ul>
-     *
-     * <p><b>Note:</b> Although the language tag created by this
-     * method is well-formed (satisfies the syntax requirements
-     * defined by the IETF BCP 47 specification), it is not
-     * necessarily a valid BCP 47 language tag.  For example,
-     * <pre>
-     *   new Locale("xx", "YY").toLanguageTag();</pre>
-     * 
-     * will return "xx-YY", but the language subtag "xx" and the
-     * region subtag "YY" are invalid because they are not registered
-     * in the IANA Language Subtag Registry.
-     *
-     * @return a BCP47 language tag representing the locale
-     * @see #forLanguageTag(String)
-     *
-     * @draft ICU 4.2
-     * @provisional This API might change or be removed in a future release.
-     */
-    public String toLanguageTag() {
-        BaseLocale base = base();
-        LocaleExtensions exts = extensions();
-
-        if (base.getVariant().equalsIgnoreCase("POSIX")) {
-            // special handling for variant POSIX
-            base = BaseLocale.getInstance(base.getLanguage(), base.getScript(), base.getRegion(), "");
-            if (exts.getUnicodeLocaleType("va") == null) {
-                // add va-posix
-                InternalLocaleBuilder ilocbld = new InternalLocaleBuilder();
-                try {
-                    ilocbld.setLocale(BaseLocale.ROOT, exts);
-                    ilocbld.setUnicodeLocaleKeyword("va", "posix");
-                    exts = ilocbld.getLocaleExtensions();
-                } catch (LocaleSyntaxException e) {
-                    // this should not happen
-                    throw new RuntimeException(e);
-                }
-            }
-        }
-
-        LanguageTag tag = LanguageTag.parseLocale(base, exts);
-
-        StringBuilder buf = new StringBuilder();
-        String subtag = tag.getLanguage();
-        if (subtag.length() > 0) {
-            buf.append(LanguageTag.canonicalizeLanguage(subtag));
-        }
- 
-        subtag = tag.getScript();
-        if (subtag.length() > 0) {
-            buf.append(LanguageTag.SEP);
-            buf.append(LanguageTag.canonicalizeScript(subtag));
-        }
-
-        subtag = tag.getRegion();
-        if (subtag.length() > 0) {
-            buf.append(LanguageTag.SEP);
-            buf.append(LanguageTag.canonicalizeRegion(subtag));
-        }
-
-        List<String>subtags = tag.getVariants();
-        for (String s : subtags) {
-            buf.append(LanguageTag.SEP);
-            buf.append(LanguageTag.canonicalizeVariant(s));
-        }
-
-        subtags = tag.getExtensions();
-        for (String s : subtags) {
-            buf.append(LanguageTag.SEP);
-            buf.append(LanguageTag.canonicalizeExtension(s));
-        }
-
-        subtag = tag.getPrivateuse();
-        if (subtag.length() > 0) {
-            if (buf.length() > 0) {
-                buf.append(LanguageTag.SEP);
-            }
-            buf.append(LanguageTag.PRIVATEUSE).append(LanguageTag.SEP);
-            buf.append(LanguageTag.canonicalizePrivateuse(subtag));
-        }
-
-        return buf.toString();
-    }
-
-    /**
-     * {@icu} Returns a locale for the specified IETF BCP 47 language tag string.
-     *
-     * <p>If the specified language tag contains any ill-formed subtags,
-     * the first such subtag and all following subtags are ignored.  Compare
-     * to {@link ULocale.Builder#setLanguageTag} which throws an exception
-     * in this case.
-     *
-     * <p>The following <b>conversions</b> are performed:<ul>
-     *
-     * <li>The language code "und" is mapped to language "".
-     *
-     * <li>The portion of a private use subtag prefixed by "lvariant",
-     * if any, is removed and appended to the variant field in the
-     * result locale (without case normalization).  If it is then
-     * empty, the private use subtag is discarded:
-     *
-     * <pre>
-     *     ULocale loc;
-     *     loc = ULocale.forLanguageTag("en-US-x-lvariant-icu4j);
-     *     loc.getVariant(); // returns "ICU4J"
-     *     loc.getExtension('x'); // returns null
-     *
-     *     loc = Locale.forLanguageTag("de-icu4j-x-URP-lvariant-Abc-Def");
-     *     loc.getVariant(); // returns "ICU4J_ABC_DEF"
-     *     loc.getExtension('x'); // returns "urp"
-     * </pre>
-     *
-     * <li>When the languageTag argument contains an extlang subtag,
-     * the first such subtag is used as the language, and the primary
-     * language subtag and other extlang subtags are ignored:
-     *
-     * <pre>
-     *     ULocale.forLanguageTag("ar-aao").getLanguage(); // returns "aao"
-     *     ULocale.forLanguageTag("en-abc-def-us").toString(); // returns "abc_US"
-     * </pre>
-     *
-     * <li>Case is normalized. Language is normalized to lower case,
-     * script to title case, country to upper case, variant to upper case,
-     * and extensions to lower case.
-     *
-     * <p>This implements the 'Language-Tag' production of BCP 47, and so
-     * supports legacy language tags (marked as “Type: grandfathered” in BCP 47)
-     * (regular and irregular) as well as private use language tags.
-     *
-     * <p>Stand-alone private use tags are represented as empty language and extension 'x-whatever',
-     * and legacy tags are converted to their canonical replacements where they exist.
-     *
-     * <p>Note that a few legacy tags have no modern replacement;
-     * these will be converted using the fallback described in
-     * the first paragraph, so some information might be lost.
-     *
-     * <p><b>Note</b>: There is no guarantee that <code>toLanguageTag</code>
-     * and <code>forLanguageTag</code> will round-trip.
-     *
-     * @param languageTag the language tag
-     * @return The locale that best represents the language tag.
-     * @throws NullPointerException if <code>languageTag</code> is <code>null</code>
-     * @see #toLanguageTag()
-     * @see ULocale.Builder#setLanguageTag(String)
-     *
-     * @draft ICU 4.2
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static ULocale forLanguageTag(String languageTag) {
-        LanguageTag tag = LanguageTag.parse(languageTag, null);
-        InternalLocaleBuilder bldr = new InternalLocaleBuilder();
-        bldr.setLanguageTag(tag);
-        return getInstance(bldr.getBaseLocale(), bldr.getLocaleExtensions());
-    }
-
-
-    /**
-     * <code>Builder</code> is used to build instances of <code>ULocale</code>
-     * from values configured by the setters.  Unlike the <code>ULocale</code>
-     * constructors, the <code>Builder</code> checks if a value configured by a
-     * setter satisfies the syntax requirements defined by the <code>ULocale</code>
-     * class.  A <code>ULocale</code> object created by a <code>Builder</code> is
-     * well-formed and can be transformed to a well-formed IETF BCP 47 language tag
-     * without losing information.
-     *
-     * <p><b>Note:</b> The <code>ULocale</code> class does not provide any
-     * syntactic restrictions on variant, while BCP 47 requires each variant
-     * subtag to be 5 to 8 alphanumerics or a single numeric followed by 3
-     * alphanumerics.  The method <code>setVariant</code> throws
-     * <code>IllformedLocaleException</code> for a variant that does not satisfy
-     * this restriction. If it is necessary to support such a variant, use a
-     * ULocale constructor.  However, keep in mind that a <code>ULocale</code>
-     * object created this way might lose the variant information when
-     * transformed to a BCP 47 language tag.
-     *
-     * <p>The following example shows how to create a <code>Locale</code> object
-     * with the <code>Builder</code>.
-     * <blockquote>
-     * <pre>
-     *     ULocale aLocale = new Builder().setLanguage("sr").setScript("Latn").setRegion("RS").build();
-     * </pre>
-     * </blockquote>
-     *
-     * <p>Builders can be reused; <code>clear()</code> resets all
-     * fields to their default values.
-     *
-     * @see ULocale#toLanguageTag()
-     *
-     * @draft ICU 4.2
-     * @provisional This API might change or be removed in a future release.
-     */
-    public static final class Builder {
-
-        private final InternalLocaleBuilder _locbld;
-
-        /**
-         * Constructs an empty Builder. The default value of all
-         * fields, extensions, and private use information is the
-         * empty string.
-         *
-         * @draft ICU 4.2
-         * @provisional This API might change or be removed in a future release.
-         */
-        public Builder() {
-            _locbld = new InternalLocaleBuilder();
-        }
-
-        /**
-         * Resets the <code>Builder</code> to match the provided
-         * <code>locale</code>.  Existing state is discarded.
-         *
-         * <p>All fields of the locale must be well-formed, see {@link Locale}.
-         *
-         * <p>Locales with any ill-formed fields cause
-         * <code>IllformedLocaleException</code> to be thrown.
-         *
-         * @param locale the locale
-         * @return This builder.
-         * @throws IllformedLocaleException if <code>locale</code> has
-         * any ill-formed fields.
-         * @throws NullPointerException if <code>locale</code> is null.
-         *
-         * @draft ICU 4.2
-         * @provisional This API might change or be removed in a future release.
-         */
-        public Builder setLocale(ULocale locale) {
-            try {
-                _locbld.setLocale(locale.base(), locale.extensions());
-            } catch (LocaleSyntaxException e) {
-                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
-            }
-            return this;
-        }
-
-        /**
-         * Resets the Builder to match the provided IETF BCP 47
-         * language tag.  Discards the existing state.  Null and the
-         * empty string cause the builder to be reset, like {@link
-         * #clear}.  Legacy tags (see {@link
-         * ULocale#forLanguageTag}) are converted to their canonical
-         * form before being processed.  Otherwise, the language tag
-         * must be well-formed (see {@link ULocale}) or an exception is
-         * thrown (unlike <code>ULocale.forLanguageTag</code>, which
-         * just discards ill-formed and following portions of the
-         * tag).
-         *
-         * @param languageTag the language tag
-         * @return This builder.
-         * @throws IllformedLocaleException if <code>languageTag</code> is ill-formed
-         * @see ULocale#forLanguageTag(String)
-         *
-         * @draft ICU 4.2
-         * @provisional This API might change or be removed in a future release.
-         */
-        public Builder setLanguageTag(String languageTag) {
-            ParseStatus sts = new ParseStatus();
-            LanguageTag tag = LanguageTag.parse(languageTag, sts);
-            if (sts.isError()) {
-                throw new IllformedLocaleException(sts.getErrorMessage(), sts.getErrorIndex());
-            }
-            _locbld.setLanguageTag(tag);
-
-            return this;
-        }
-
-        /**
-         * Sets the language.  If <code>language</code> is the empty string or
-         * null, the language in this <code>Builder</code> is removed.  Otherwise,
-         * the language must be <a href="./Locale.html#def_language">well-formed</a>
-         * or an exception is thrown.
-         *
-         * <p>The typical language value is a two or three-letter language
-         * code as defined in ISO639.
-         *
-         * @param language the language
-         * @return This builder.
-         * @throws IllformedLocaleException if <code>language</code> is ill-formed
-         *
-         * @draft ICU 4.2
-         * @provisional This API might change or be removed in a future release.
-         */
-        public Builder setLanguage(String language) {
-            try {
-                _locbld.setLanguage(language);
-            } catch (LocaleSyntaxException e) {
-                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
-            }
-            return this;
-        }
-
-        /**
-         * Sets the script. If <code>script</code> is null or the empty string,
-         * the script in this <code>Builder</code> is removed.
-         * Otherwise, the script must be well-formed or an exception is thrown.
-         *
-         * <p>The typical script value is a four-letter script code as defined by ISO 15924.
-         *
-         * @param script the script
-         * @return This builder.
-         * @throws IllformedLocaleException if <code>script</code> is ill-formed
-         *
-         * @draft ICU 4.2
-         * @provisional This API might change or be removed in a future release.
-         */
-        public Builder setScript(String script) {
-            try {
-                _locbld.setScript(script);
-            } catch (LocaleSyntaxException e) {
-                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
-            }
-            return this;
-        }
-
-        /**
-         * Sets the region.  If region is null or the empty string, the region
-         * in this <code>Builder</code> is removed.  Otherwise,
-         * the region must be well-formed or an exception is thrown.
-         *
-         * <p>The typical region value is a two-letter ISO 3166 code or a
-         * three-digit UN M.49 area code.
-         *
-         * <p>The country value in the <code>Locale</code> created by the
-         * <code>Builder</code> is always normalized to upper case.
-         *
-         * @param region the region
-         * @return This builder.
-         * @throws IllformedLocaleException if <code>region</code> is ill-formed
-         *
-         * @draft ICU 4.2
-         * @provisional This API might change or be removed in a future release.
-         */
-        public Builder setRegion(String region) {
-            try {
-                _locbld.setRegion(region);
-            } catch (LocaleSyntaxException e) {
-                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
-            }
-            return this;
-        }
-
-        /**
-         * Sets the variant.  If variant is null or the empty string, the
-         * variant in this <code>Builder</code> is removed.  Otherwise, it
-         * must consist of one or more well-formed subtags, or an exception is thrown.
-         *
-         * <p><b>Note:</b> This method checks if <code>variant</code>
-         * satisfies the IETF BCP 47 variant subtag's syntax requirements,
-         * and normalizes the value to lowercase letters.  However,
-         * the <code>ULocale</code> class does not impose any syntactic
-         * restriction on variant.  To set such a variant,
-         * use a ULocale constructor.
-         *
-         * @param variant the variant
-         * @return This builder.
-         * @throws IllformedLocaleException if <code>variant</code> is ill-formed
-         *
-         * @draft ICU 4.2
-         * @provisional This API might change or be removed in a future release.
-         */
-        public Builder setVariant(String variant) {
-            try {
-                _locbld.setVariant(variant);
-            } catch (LocaleSyntaxException e) {
-                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
-            }
-            return this;
-        }
-
-        /**
-         * Sets the extension for the given key. If the value is null or the
-         * empty string, the extension is removed.  Otherwise, the extension
-         * must be well-formed or an exception is thrown.
-         *
-         * <p><b>Note:</b> The key {@link ULocale#UNICODE_LOCALE_EXTENSION
-         * UNICODE_LOCALE_EXTENSION} ('u') is used for the Unicode locale extension.
-         * Setting a value for this key replaces any existing Unicode locale key/type
-         * pairs with those defined in the extension.
-         *
-         * <p><b>Note:</b> The key {@link ULocale#PRIVATE_USE_EXTENSION
-         * PRIVATE_USE_EXTENSION} ('x') is used for the private use code. To be
-         * well-formed, the value for this key needs only to have subtags of one to
-         * eight alphanumeric characters, not two to eight as in the general case.
-         *
-         * @param key the extension key
-         * @param value the extension value
-         * @return This builder.
-         * @throws IllformedLocaleException if <code>key</code> is illegal
-         * or <code>value</code> is ill-formed
-         * @see #setUnicodeLocaleKeyword(String, String)
-         *
-         * @draft ICU 4.2
-         * @provisional This API might change or be removed in a future release.
-         */
-        public Builder setExtension(char key, String value) {
-            try {
-                _locbld.setExtension(key, value);
-            } catch (LocaleSyntaxException e) {
-                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
-            }
-            return this;
-        }
-
-        /**
-         * Sets the Unicode locale keyword type for the given key.  If the type
-         * is null, the Unicode keyword is removed.  Otherwise, the key must be
-         * non-null and both key and type must be well-formed or an exception
-         * is thrown.
-         *
-         * <p>Keys and types are converted to lower case.
-         *
-         * <p><b>Note</b>:Setting the 'u' extension via {@link #setExtension}
-         * replaces all Unicode locale keywords with those defined in the
-         * extension.
-         *
-         * @param key the Unicode locale key
-         * @param type the Unicode locale type
-         * @return This builder.
-         * @throws IllformedLocaleException if <code>key</code> or <code>type</code>
-         * is ill-formed
-         * @throws NullPointerException if <code>key</code> is null
-         * @see #setExtension(char, String)
-         *
-         * @draft ICU 4.4
-         * @provisional This API might change or be removed in a future release.
-         */
-        public Builder setUnicodeLocaleKeyword(String key, String type) {
-            try {
-                _locbld.setUnicodeLocaleKeyword(key, type);
-            } catch (LocaleSyntaxException e) {
-                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
-            }
-            return this;
-        }
-
-        /**
-         * Adds a unicode locale attribute, if not already present, otherwise
-         * has no effect.  The attribute must not be null and must be well-formed
-         * or an exception is thrown.
-         *
-         * @param attribute the attribute
-         * @return This builder.
-         * @throws NullPointerException if <code>attribute</code> is null
-         * @throws IllformedLocaleException if <code>attribute</code> is ill-formed
-         * @see #setExtension(char, String)
-         *
-         * @draft ICU 4.6
-         * @provisional This API might change or be removed in a future release.
-         */
-        public Builder addUnicodeLocaleAttribute(String attribute) {
-            try {
-                _locbld.addUnicodeLocaleAttribute(attribute);
-            } catch (LocaleSyntaxException e) {
-                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
-            }
-            return this;
-        }
-
-        /**
-         * Removes a unicode locale attribute, if present, otherwise has no
-         * effect.  The attribute must not be null and must be well-formed
-         * or an exception is thrown.
-         *
-         * <p>Attribute comparison for removal is case-insensitive.
-         *
-         * @param attribute the attribute
-         * @return This builder.
-         * @throws NullPointerException if <code>attribute</code> is null
-         * @throws IllformedLocaleException if <code>attribute</code> is ill-formed
-         * @see #setExtension(char, String)
-         *
-         * @draft ICU 4.6
-         * @provisional This API might change or be removed in a future release.
-         */
-        public Builder removeUnicodeLocaleAttribute(String attribute) {
-            try {
-                _locbld.removeUnicodeLocaleAttribute(attribute);
-            } catch (LocaleSyntaxException e) {
-                throw new IllformedLocaleException(e.getMessage(), e.getErrorIndex());
-            }
-            return this;
-        }
-
-        /**
-         * Resets the builder to its initial, empty state.
-         *
-         * @return this builder
-         *
-         * @draft ICU 4.2
-         * @provisional This API might change or be removed in a future release.
-         */
-        public Builder clear() {
-            _locbld.clear();
-            return this;
-        }
-
-        /**
-         * Resets the extensions to their initial, empty state.
-         * Language, script, region and variant are unchanged.
-         *
-         * @return this builder
-         * @see #setExtension(char, String)
-         *
-         * @draft ICU 4.2
-         * @provisional This API might change or be removed in a future release.
-         */
-        public Builder clearExtensions() {
-            _locbld.clearExtensions();
-            return this;
-        }
-
-        /**
-         * Returns an instance of <code>ULocale</code> created from the fields set
-         * on this builder.
-         *
-         * @return a new Locale
-         *
-         * @draft ICU 4.4
-         * @provisional This API might change or be removed in a future release.
-         */
-        public ULocale build() {
-            return getInstance(_locbld.getBaseLocale(), _locbld.getLocaleExtensions());
-        }
-    }
-
-    private static ULocale getInstance(BaseLocale base, LocaleExtensions exts) {
-        String id = lscvToID(base.getLanguage(), base.getScript(), base.getRegion(),
-                base.getVariant());
-
-        Set<Character> extKeys = exts.getKeys();
-        if (!extKeys.isEmpty()) {
-            // legacy locale ID assume Unicode locale keywords and
-            // other extensions are at the same level.
-            // e.g. @a=ext-for-aa;calendar=japanese;m=ext-for-mm;x=priv-use
-
-            TreeMap<String, String> kwds = new TreeMap<String, String>();
-            for (Character key : extKeys) {
-                Extension ext = exts.getExtension(key);
-                if (ext instanceof UnicodeLocaleExtension) {
-                    UnicodeLocaleExtension uext = (UnicodeLocaleExtension)ext;
-                    Set<String> ukeys = uext.getUnicodeLocaleKeys();
-                    for (String bcpKey : ukeys) {
-                        String bcpType = uext.getUnicodeLocaleType(bcpKey);
-                        // convert to legacy key/type
-                        String lkey = bcp47ToLDMLKey(bcpKey);
-                        String ltype = bcp47ToLDMLType(lkey, ((bcpType.length() == 0) ? "yes" : bcpType)); // use "yes" as the value of typeless keywords
-                        // special handling for u-va-posix, since this is a variant, not a keyword
-                        if (lkey.equals("va") && ltype.equals("posix") && base.getVariant().length() == 0) {
-                            id = id + "_POSIX";
-                        } else {
-                            kwds.put(lkey, ltype);
-                        }
-                    }
-                    // Mapping Unicode locale attribute to the special keyword, attribute=xxx-yyy
-                    Set<String> uattributes = uext.getUnicodeLocaleAttributes();
-                    if (uattributes.size() > 0) {
-                        StringBuilder attrbuf = new StringBuilder();
-                        for (String attr : uattributes) {
-                            if (attrbuf.length() > 0) {
-                                attrbuf.append('-');
-                            }
-                            attrbuf.append(attr);
-                        }
-                        kwds.put(LOCALE_ATTRIBUTE_KEY, attrbuf.toString());
-                    }
-                } else {
-                    kwds.put(String.valueOf(key), ext.getValue());
-                }
-            }
-
-            if (!kwds.isEmpty()) {
-                StringBuilder buf = new StringBuilder(id);
-                buf.append("@");
-                Set<Map.Entry<String, String>> kset = kwds.entrySet();
-                boolean insertSep = false;
-                for (Map.Entry<String, String> kwd : kset) {
-                    if (insertSep) {
-                        buf.append(";");
-                    } else {
-                        insertSep = true;
-                    }
-                    buf.append(kwd.getKey());
-                    buf.append("=");
-                    buf.append(kwd.getValue());
-                }
-
-                id = buf.toString();
-            }
-        }
-        return new ULocale(id);
-    }
-
-    private BaseLocale base() {
-        if (baseLocale == null) {
-            String language = getLanguage();
-            if (equals(ULocale.ROOT)) {
-                language = "";
-            }
-            baseLocale = BaseLocale.getInstance(language, getScript(), getCountry(), getVariant());
-        }
-        return baseLocale;
-    }
-
-    private LocaleExtensions extensions() {
-        if (extensions == null) {
-            Iterator<String> kwitr = getKeywords();
-            if (kwitr == null) {
-                extensions = LocaleExtensions.EMPTY_EXTENSIONS;
-            } else {
-                InternalLocaleBuilder intbld = new InternalLocaleBuilder();
-                while (kwitr.hasNext()) {
-                    String key = kwitr.next();
-                    if (key.equals(LOCALE_ATTRIBUTE_KEY)) {
-                        // special keyword used for representing Unicode locale attributes
-                        String[] uattributes = getKeywordValue(key).split("[-_]");
-                        for (String uattr : uattributes) {
-                            try {
-                                intbld.addUnicodeLocaleAttribute(uattr);
-                            } catch (LocaleSyntaxException e) {
-                                // ignore and fall through
-                            }
-                        }
-                    } else if (key.length() >= 2) {
-                        String bcpKey = ldmlKeyToBCP47(key);
-                        String bcpType = ldmlTypeToBCP47(key, getKeywordValue(key));
-                        if (bcpKey != null && bcpType != null) {
-                            try {
-                                intbld.setUnicodeLocaleKeyword(bcpKey, bcpType);
-                            } catch (LocaleSyntaxException e) {
-                                // ignore and fall through
-                            }
-                        }
-                    } else if (key.length() == 1 && (key.charAt(0) != UNICODE_LOCALE_EXTENSION)) {
-                        try  {
-                            intbld.setExtension(key.charAt(0), getKeywordValue(key).replace("_",
-                                    LanguageTag.SEP));
-                        } catch (LocaleSyntaxException e) {
-                            // ignore and fall through
-                        }
-                    }
-                }
-                extensions = intbld.getLocaleExtensions();
-            }
-        }
-        return extensions;
-    }
-
-    //
-    // LDML legacy/BCP47 key and type mapping functions
-    //
-    private static String ldmlKeyToBCP47(String key) {
-        //#com.ibm.icu.base
-        // normalize key to lowercase
-        key = AsciiUtil.toLowerString(key);
-        String bcpKey = null;
-
-        for (int i = 0; i < KEYMAP.length; i += 2) {
-            if (key.equals(KEYMAP[i])) {
-                bcpKey = KEYMAP[i + 1];
-                break;
-            }
-        }
-
-        if (bcpKey == null) {
-            if (key.length() == 2 && LanguageTag.isExtensionSubtag(key)) {
-                return key;
-            }
-            return null;
-        }
-
-        return bcpKey;
-    }
-
-    private static String bcp47ToLDMLKey(String bcpKey) {
-        //#com.ibm.icu.base
-        // normalize bcp key to lowercase
-        bcpKey = AsciiUtil.toLowerString(bcpKey);
-        String key = null;
-
-        for (int i = 0; i < KEYMAP.length; i += 2) {
-            if (bcpKey.equals(KEYMAP[i + 1])) {
-                key = KEYMAP[i];
-                break;
-            }
-        }
-
-        if (key == null) {
-            return bcpKey;
-        }
-
-        return key;
-    }
-
-    private static String ldmlTypeToBCP47(String key, String type) {
-        //#com.ibm.icu.base
-
-        // keys are case-insensitive, while types are case-sensitive
-        key = AsciiUtil.toLowerString(key);
-        String bcpType = null;
-        String[] map = null;
-        String[] aliasMap = null;
-
-        if (key.equals("calendar")) {
-            map = TYPEMAP_CALENDAR;
-        } else if (key.equals("colalternate")) {
-            map = TYPEMAP_COLALTERNATE;
-        } else if (key.equals("colbackwards")) {
-            map = TYPEMAP_COLBACKWARDS;
-        } else if (key.equals("colcasefirst")) {
-            map = TYPEMAP_COLCASEFIRST;
-        } else if (key.equals("colcaselevel")) {
-            map = TYPEMAP_COLCASELEVEL;
-        } else if (key.equals("colhiraganaquaternary")) {
-            map = TYPEMAP_COLHIRAGANAQUATERNARY;
-        } else if (key.equals("collation")) {
-            map = TYPEMAP_COLLATION;
-        } else if (key.equals("colnormalization")) {
-            map = TYPEMAP_COLNORMALIZATION;
-        } else if (key.equals("colnumeric")) {
-            map = TYPEMAP_COLNUMERIC;
-        } else if (key.equals("colstrength")) {
-            map = TYPEMAP_COLSTRENGTH;
-            aliasMap = TYPEALIAS_COLSTRENGTH;
-        } else if (key.equals("numbers")) {
-            map = TYPEMAP_NUMBERS;
-        } else if (key.equals("timezone")) {
-            map = TYPEMAP_TIMEZONE;
-            aliasMap = TYPEALIAS_TIMEZONE;
-        }
-
-        // LDML alias -> LDML canonical
-        if (aliasMap != null) {
-            for (int i = 0; i < aliasMap.length; i += 2) {
-                if (type.equals(aliasMap[i])) {
-                    type = aliasMap[i + 1];
-                    break;
-                }
-            }
-        }
-
-        // LDML type -> BCP47 type
-        if (map != null) {
-            for (int i = 0; i < map.length; i += 2) {
-                if (type.equals(map[i])) {
-                    bcpType = map[i + 1];
-                    break;
-                }
-            }
-        }
-
-        if (bcpType == null) {
-            int typeLen = type.length();
-            if (typeLen >= 3 && typeLen <= 8 && LanguageTag.isExtensionSubtag(type)) {
-                return type;
-            }
-            return null;
-        }
-        return bcpType;
-    }
-
-    private static String bcp47ToLDMLType(String key, String bcpType) {
-        //#com.ibm.icu.base
-
-        // normalize key/bcpType to lowercase
-        key = AsciiUtil.toLowerString(key);
-        bcpType = AsciiUtil.toLowerString(bcpType);
-        String type = null;
-        String[] map = null;
-
-        if (key.equals("calendar")) {
-            map = TYPEMAP_CALENDAR;
-        } else if (key.equals("colalternate")) {
-            map = TYPEMAP_COLALTERNATE;
-        } else if (key.equals("colbackwards")) {
-            map = TYPEMAP_COLBACKWARDS;
-        } else if (key.equals("colcasefirst")) {
-            map = TYPEMAP_COLCASEFIRST;
-        } else if (key.equals("colcaselevel")) {
-            map = TYPEMAP_COLCASELEVEL;
-        } else if (key.equals("colhiraganaquaternary")) {
-            map = TYPEMAP_COLHIRAGANAQUATERNARY;
-        } else if (key.equals("collation")) {
-            map = TYPEMAP_COLLATION;
-        } else if (key.equals("colnormalization")) {
-            map = TYPEMAP_COLNORMALIZATION;
-        } else if (key.equals("colnumeric")) {
-            map = TYPEMAP_COLNUMERIC;
-        } else if (key.equals("colstrength")) {
-            map = TYPEMAP_COLSTRENGTH;
-        } else if (key.equals("timezone")) {
-            map = TYPEMAP_TIMEZONE;
-        }
-
-        if (map != null) {
-            for (int i = 0; i < map.length; i += 2) {
-                if (bcpType.equals(map[i + 1])) {
-                    type = map[i];
-                    break;
-                }
-            }
-        }
-
-        return (type != null) ? type : bcpType;
-    }
-
-    /*
-     * JDK Locale Helper
-     */
-    private static final class JDKLocaleHelper {
-        private static boolean isJava7orNewer = false;
-
-        /*
-         * New methods in Java 7 Locale class
-         */
-        private static Method mGetScript;
-        private static Method mGetExtensionKeys;
-        private static Method mGetExtension;
-        private static Method mGetUnicodeLocaleKeys;
-        private static Method mGetUnicodeLocaleAttributes;
-        private static Method mGetUnicodeLocaleType;
-        private static Method mForLanguageTag;
-
-        private static Method mGetDefault;
-        private static Method mSetDefault;
-        private static Object eDISPLAY;
-        private static Object eFORMAT;
-
-        /*
-         * This table is used for mapping between ICU and special Java
-         * 6 locales.  When an ICU locale matches <minumum base> with
-         * <keyword>/<value>, the ICU locale is mapped to <Java> locale.
-         * For example, both ja_JP@calendar=japanese and ja@calendar=japanese
-         * are mapped to Java locale "ja_JP_JP".  ICU locale "nn" is mapped
-         * to Java locale "no_NO_NY".
-         */
-        private static final String[][] JAVA6_MAPDATA = {
-        //  { <Java>,       <ICU base>, <keyword>,  <value>,    <minimum base>
-            { "ja_JP_JP",   "ja_JP",    "calendar", "japanese", "ja"},
-            { "no_NO_NY",   "nn_NO",    null,       null,       "nn"},
-            { "th_TH_TH",   "th_TH",    "numbers",  "thai",     "th"},
-        };
-
-        static {
-            do {
-                try {
-                    mGetScript = Locale.class.getMethod("getScript", (Class[]) null);
-                    mGetExtensionKeys = Locale.class.getMethod("getExtensionKeys", (Class[]) null);
-                    mGetExtension = Locale.class.getMethod("getExtension", char.class);
-                    mGetUnicodeLocaleKeys = Locale.class.getMethod("getUnicodeLocaleKeys", (Class[]) null);
-                    mGetUnicodeLocaleAttributes = Locale.class.getMethod("getUnicodeLocaleAttributes", (Class[]) null);
-                    mGetUnicodeLocaleType = Locale.class.getMethod("getUnicodeLocaleType", String.class);
-                    mForLanguageTag = Locale.class.getMethod("forLanguageTag", String.class);
-    
-                    Class<?> cCategory = null;
-                    Class<?>[] classes = Locale.class.getDeclaredClasses();
-                    for (Class<?> c : classes) {
-                        if (c.getName().equals("java.util.Locale$Category")) {
-                            cCategory = c;
-                            break;
-                        }
-                    }
-                    if (cCategory == null) {
-                        break;
-                    }
-                    mGetDefault = Locale.class.getDeclaredMethod("getDefault", cCategory);
-                    mSetDefault = Locale.class.getDeclaredMethod("setDefault", cCategory, Locale.class);
-    
-                    Method mName = cCategory.getMethod("name", (Class[]) null);
-                    Object[] enumConstants = cCategory.getEnumConstants();
-                    for (Object e : enumConstants) {
-                        String catVal = (String)mName.invoke(e, (Object[])null);
-                        if (catVal.equals("DISPLAY")) {
-                            eDISPLAY = e;
-                        } else if (catVal.equals("FORMAT")) {
-                            eFORMAT = e;
-                        }
-                    }
-                    if (eDISPLAY == null || eFORMAT == null) {
-                        break;
-                    }    
-                    isJava7orNewer = true;
-                } catch (NoSuchMethodException e) {
-                } catch (IllegalArgumentException e) {
-                } catch (IllegalAccessException e) {
-                } catch (InvocationTargetException e) {
-                } catch (SecurityException e) {
-                    // TODO : report?
-                }
-            } while (false);
-        }
-
-        private JDKLocaleHelper() {
-        }
-
-        public static boolean isJava7orNewer() {
-            return isJava7orNewer;
-        }
-
-        public static ULocale toULocale(Locale loc) {
-            return isJava7orNewer ? toULocale7(loc) : toULocale6(loc);
-        }
-
-        public static Locale toLocale(ULocale uloc) {
-            return isJava7orNewer ? toLocale7(uloc) : toLocale6(uloc);
-        }
-
-        private static ULocale toULocale7(Locale loc) {
-            String language = loc.getLanguage();
-            String script = "";
-            String country = loc.getCountry();
-            String variant = loc.getVariant();
-
-            Set<String> attributes = null;
-            Map<String, String> keywords = null;
-
-            try {
-                script = (String) mGetScript.invoke(loc, (Object[]) null);
-                @SuppressWarnings("unchecked")
-                Set<Character> extKeys = (Set<Character>) mGetExtensionKeys.invoke(loc, (Object[]) null);
-                if (!extKeys.isEmpty()) {
-                    for (Character extKey : extKeys) {
-                        if (extKey.charValue() == 'u') {
-                            // Found Unicode locale extension
-
-                            // attributes
-                            @SuppressWarnings("unchecked")
-                            Set<String> uAttributes = (Set<String>) mGetUnicodeLocaleAttributes.invoke(loc, (Object[]) null);
-                            if (!uAttributes.isEmpty()) {
-                                attributes = new TreeSet<String>();
-                                for (String attr : uAttributes) {
-                                    attributes.add(attr);
-                                }
-                            }
-
-                            // keywords
-                            @SuppressWarnings("unchecked")
-                            Set<String> uKeys = (Set<String>) mGetUnicodeLocaleKeys.invoke(loc, (Object[]) null);
-                            for (String kwKey : uKeys) {
-                                String kwVal = (String) mGetUnicodeLocaleType.invoke(loc, kwKey);
-                                if (kwVal != null) {
-                                    if (kwKey.equals("va")) {
-                                        // va-* is interpreted as a variant
-                                        variant = (variant.length() == 0) ? kwVal : kwVal + "_" + variant;
-                                    } else {
-                                        if (keywords == null) {
-                                            keywords = new TreeMap<String, String>();
-                                        }
-                                        keywords.put(kwKey, kwVal);
-                                    }
-                                }
-                            }
-                        } else {
-                            String extVal = (String) mGetExtension.invoke(loc, extKey);
-                            if (extVal != null) {
-                                if (keywords == null) {
-                                    keywords = new TreeMap<String, String>();
-                                }
-                                keywords.put(String.valueOf(extKey), extVal);
-                            }
-                        }
-                    }
-                }
-            } catch (IllegalAccessException e) {
-                throw new RuntimeException(e);
-            } catch (InvocationTargetException e) {
-                throw new RuntimeException(e);
-            }
-
-            // JDK locale no_NO_NY is not interpreted as Nynorsk by ICU,
-            // and it should be transformed to nn_NO.
-
-            // Note: JDK7+ unerstand both no_NO_NY and nn_NO. When convert
-            // ICU locale to JDK, we do not need to map nn_NO back to no_NO_NY.
-
-            if (language.equals("no") && country.equals("NO") && variant.equals("NY")) {
-                language = "nn";
-                variant = "";
-            }
-
-            // Constructing ID
-            StringBuilder buf = new StringBuilder(language);
-
-            if (script.length() > 0) {
-                buf.append('_');
-                buf.append(script);
-            }
-
-            if (country.length() > 0) {
-                buf.append('_');
-                buf.append(country);
-            }
-
-            if (variant.length() > 0) {
-                if (country.length() == 0) {
-                    buf.append('_');
-                }
-                buf.append('_');
-                buf.append(variant);
-            }
-
-            if (attributes != null) {
-                // transform Unicode attributes into a keyword
-                StringBuilder attrBuf = new StringBuilder();
-                for (String attr : attributes) {
-                    if (attrBuf.length() != 0) {
-                        attrBuf.append('-');
-                    }
-                    attrBuf.append(attr);
-                }
-                if (keywords == null) {
-                    keywords = new TreeMap<String, String>();
-                }
-                keywords.put(LOCALE_ATTRIBUTE_KEY, attrBuf.toString());
-            }
-
-            if (keywords != null) {
-                buf.append('@');
-                boolean addSep = false;
-                for (Entry<String, String> kwEntry : keywords.entrySet()) {
-                    String kwKey = kwEntry.getKey();
-                    String kwVal = kwEntry.getValue();
-
-                    if (kwKey.length() != 1) {
-                        // Unicode locale key
-                        kwKey = bcp47ToLDMLKey(kwKey);
-                        // use "yes" as the value of typeless keywords
-                        kwVal = bcp47ToLDMLType(kwKey, ((kwVal.length() == 0) ? "yes" : kwVal));
-                    }
-
-                    if (addSep) {
-                        buf.append(';');
-                    } else {
-                        addSep = true;
-                    }
-                    buf.append(kwKey);
-                    buf.append('=');
-                    buf.append(kwVal);
-                }
-            }
-
-            return new ULocale(getName(buf.toString()), loc);
-        }
-
-        private static ULocale toULocale6(Locale loc) {
-            ULocale uloc = null;
-            String locStr = loc.toString();
-            if (locStr.length() == 0) {
-                uloc = ULocale.ROOT;
-            } else {
-                for (int i = 0; i < JAVA6_MAPDATA.length; i++) {
-                    if (JAVA6_MAPDATA[i][0].equals(locStr)) {
-                        LocaleIDParser p = new LocaleIDParser(JAVA6_MAPDATA[i][1]);
-                        p.setKeywordValue(JAVA6_MAPDATA[i][2], JAVA6_MAPDATA[i][3]);
-                        locStr = p.getName();
-                        break;
-                    }
-                }
-                uloc = new ULocale(getName(locStr), loc);
-            }
-            return uloc;
-        }
-
-        private static Locale toLocale7(ULocale uloc) {
-            Locale loc = null;
-            String ulocStr = uloc.getName();
-            if (uloc.getScript().length() > 0 || ulocStr.contains("@")) {
-                // With script or keywords available, the best way
-                // to get a mapped Locale is to go through a language tag.
-                // A Locale with script or keywords can only have variants
-                // that is 1 to 8 alphanum. If this ULocale has a variant
-                // subtag not satisfying the criteria, the variant subtag
-                // will be lost.
-                String tag = uloc.toLanguageTag();
-
-                // Workaround for variant casing problem:
-                //
-                // The variant field in ICU is case insensitive and normalized
-                // to upper case letters by getVariant(), while
-                // the variant field in JDK Locale is case sensitive.
-                // ULocale#toLanguageTag use lower case characters for
-                // BCP 47 variant and private use x-lvariant.
-                //
-                // Locale#forLanguageTag in JDK preserves character casing
-                // for variant. Because ICU always normalizes variant to
-                // upper case, we convert language tag to upper case here.
-                tag = AsciiUtil.toUpperString(tag);
-
-                try {
-                    loc = (Locale)mForLanguageTag.invoke(null, tag);
-                } catch (IllegalAccessException e) {
-                    throw new RuntimeException(e);
-                } catch (InvocationTargetException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-            if (loc == null) {
-                // Without script or keywords, use a Locale constructor,
-                // so we can preserve any ill-formed variants.
-                loc = new Locale(uloc.getLanguage(), uloc.getCountry(), uloc.getVariant());
-            }
-            return loc;
-        }
-
-        private static Locale toLocale6(ULocale uloc) {
-            String locstr = uloc.getBaseName();
-            for (int i = 0; i < JAVA6_MAPDATA.length; i++) {
-                if (locstr.equals(JAVA6_MAPDATA[i][1]) || locstr.equals(JAVA6_MAPDATA[i][4])) {
-                    if (JAVA6_MAPDATA[i][2] != null) {
-                        String val = uloc.getKeywordValue(JAVA6_MAPDATA[i][2]);
-                        if (val != null && val.equals(JAVA6_MAPDATA[i][3])) {
-                            locstr = JAVA6_MAPDATA[i][0];
-                            break;
-                        }
-                    } else {
-                        locstr = JAVA6_MAPDATA[i][0];
-                        break;
-                    }
-                }
-            }
-            LocaleIDParser p = new LocaleIDParser(locstr);
-            String[] names = p.getLanguageScriptCountryVariant();
-            return new Locale(names[0], names[2], names[3]);
-        }
-
-        public static Locale getDefault(Category category) {
-            Locale loc = Locale.getDefault();
-            if (isJava7orNewer) {
-                Object cat = null;
-                switch (category) {
-                case DISPLAY:
-                    cat = eDISPLAY;
-                    break;
-                case FORMAT:
-                    cat = eFORMAT;
-                    break;
-                }
-                if (cat != null) {
-                    try {
-                        loc = (Locale)mGetDefault.invoke(null, cat);
-                    } catch (InvocationTargetException e) {
-                        // fall through - use the base default
-                    } catch (IllegalArgumentException e) {
-                        // fall through - use the base default
-                    } catch (IllegalAccessException e) {
-                        // fall through - use the base default
-                    }
-                }
-            }
-            return loc;
-        }
-
-        public static void setDefault(Category category, Locale newLocale) {
-            if (isJava7orNewer) {
-                Object cat = null;
-                switch (category) {
-                case DISPLAY:
-                    cat = eDISPLAY;
-                    break;
-                case FORMAT:
-                    cat = eFORMAT;
-                    break;
-                }
-                if (cat != null) {
-                    try {
-                        mSetDefault.invoke(null, cat, newLocale);
-                    } catch (InvocationTargetException e) {
-                        // fall through - no effects
-                    } catch (IllegalArgumentException e) {
-                        // fall through - no effects
-                    } catch (IllegalAccessException e) {
-                        // fall through - no effects
-                    }
-                }
-            }
-        }
-    }
-
-    private static final String[] KEYMAP = {
-        "calendar", "ca",
-        "colalternate", "ka",
-        "colbackwards", "kb",
-        "colcasefirst", "kf",
-        "colcaselevel", "kc",
-        "colhiraganaquaternary", "kh",
-        "collation", "co",
-        "colnormalization", "kk",
-        "colnumeric", "kn",
-        "colstrength", "ks",
-        "currency", "cu",
-        "numbers", "nu",
-        "timezone", "tz",
-        "variabletop", "vt",
-    };
-
-    private static final String[] TYPEMAP_CALENDAR = {
-        "ethiopic-amete-alem", "ethioaa",
-        "gregorian", "gregory",
-        "islamic-civil", "islamicc",
-    };
-
-    private static final String[] TYPEMAP_COLALTERNATE = {
-        "non-ignorable", "noignore",
-    };
-
-    private static final String[] TYPEMAP_COLBACKWARDS = {
-        "no", "false",
-        "yes", "true",
-    };
-
-    private static final String[] TYPEMAP_COLCASEFIRST = {
-        "no", "false",
-    };
-
-    private static final String[] TYPEMAP_COLCASELEVEL = {
-        "no", "false",
-        "yes", "true",
-    };
-
-    private static final String[] TYPEMAP_COLHIRAGANAQUATERNARY = {
-        "no", "false",
-        "yes", "true",
-    };
-
-    private static final String[] TYPEMAP_COLLATION = {
-        "dictionary", "dict",
-        "gb2312han", "gb2312",
-        "phonebook", "phonebk",
-        "traditional", "trad",
-    };
-
-    private static final String[] TYPEMAP_COLNORMALIZATION = {
-        "no", "false",
-        "yes", "true",
-    };
-
-    private static final String[] TYPEMAP_COLNUMERIC = {
-        "no", "false",
-        "yes", "true",
-    };
-
-    private static final String[] TYPEMAP_COLSTRENGTH = {
-        "identical", "identic",
-        "primary", "level1",
-        "quaternary", "level4",
-        "secondary", "level2",
-        "tertiary", "level3",
-    };
-
-    private static final String[] TYPEMAP_NUMBERS = {
-        "traditional", "traditio",
-    };
-
-    private static final String[] TYPEMAP_TIMEZONE = {
-        "Africa/Abidjan", "ciabj",
-        "Africa/Accra", "ghacc",
-        "Africa/Addis_Ababa", "etadd",
-        "Africa/Algiers", "dzalg",
-        "Africa/Asmera", "erasm",
-        "Africa/Bamako", "mlbko",
-        "Africa/Bangui", "cfbgf",
-        "Africa/Banjul", "gmbjl",
-        "Africa/Bissau", "gwoxb",
-        "Africa/Blantyre", "mwblz",
-        "Africa/Brazzaville", "cgbzv",
-        "Africa/Bujumbura", "bibjm",
-        "Africa/Cairo", "egcai",
-        "Africa/Casablanca", "macas",
-        "Africa/Ceuta", "esceu",
-        "Africa/Conakry", "gncky",
-        "Africa/Dakar", "sndkr",
-        "Africa/Dar_es_Salaam", "tzdar",
-        "Africa/Djibouti", "djjib",
-        "Africa/Douala", "cmdla",
-        "Africa/El_Aaiun", "eheai",
-        "Africa/Freetown", "slfna",
-        "Africa/Gaborone", "bwgbe",
-        "Africa/Harare", "zwhre",
-        "Africa/Johannesburg", "zajnb",
-        "Africa/Juba", "ssjub",
-        "Africa/Kampala", "ugkla",
-        "Africa/Khartoum", "sdkrt",
-        "Africa/Kigali", "rwkgl",
-        "Africa/Kinshasa", "cdfih",
-        "Africa/Lagos", "nglos",
-        "Africa/Libreville", "galbv",
-        "Africa/Lome", "tglfw",
-        "Africa/Luanda", "aolad",
-        "Africa/Lubumbashi", "cdfbm",
-        "Africa/Lusaka", "zmlun",
-        "Africa/Malabo", "gqssg",
-        "Africa/Maputo", "mzmpm",
-        "Africa/Maseru", "lsmsu",
-        "Africa/Mbabane", "szqmn",
-        "Africa/Mogadishu", "somgq",
-        "Africa/Monrovia", "lrmlw",
-        "Africa/Nairobi", "kenbo",
-        "Africa/Ndjamena", "tdndj",
-        "Africa/Niamey", "nenim",
-        "Africa/Nouakchott", "mrnkc",
-        "Africa/Ouagadougou", "bfoua",
-        "Africa/Porto-Novo", "bjptn",
-        "Africa/Sao_Tome", "sttms",
-        "Africa/Tripoli", "lytip",
-        "Africa/Tunis", "tntun",
-        "Africa/Windhoek", "nawdh",
-        "America/Adak", "usadk",
-        "America/Anchorage", "usanc",
-        "America/Anguilla", "aiaxa",
-        "America/Antigua", "aganu",
-        "America/Araguaina", "braux",
-        "America/Argentina/La_Rioja", "arirj",
-        "America/Argentina/Rio_Gallegos", "arrgl",
-        "America/Argentina/Salta", "arsla",
-        "America/Argentina/San_Juan", "aruaq",
-        "America/Argentina/San_Luis", "arluq",
-        "America/Argentina/Tucuman", "artuc",
-        "America/Argentina/Ushuaia", "arush",
-        "America/Aruba", "awaua",
-        "America/Asuncion", "pyasu",
-        "America/Bahia", "brssa",
-        "America/Bahia_Banderas", "mxpvr",
-        "America/Barbados", "bbbgi",
-        "America/Belem", "brbel",
-        "America/Belize", "bzbze",
-        "America/Blanc-Sablon", "caybx",
-        "America/Boa_Vista", "brbvb",
-        "America/Bogota", "cobog",
-        "America/Boise", "usboi",
-        "America/Buenos_Aires", "arbue",
-        "America/Cambridge_Bay", "caycb",
-        "America/Campo_Grande", "brcgr",
-        "America/Cancun", "mxcun",
-        "America/Caracas", "veccs",
-        "America/Catamarca", "arctc",
-        "America/Cayenne", "gfcay",
-        "America/Cayman", "kygec",
-        "America/Chicago", "uschi",
-        "America/Chihuahua", "mxchi",
-        "America/Coral_Harbour", "cayzs",
-        "America/Cordoba", "arcor",
-        "America/Costa_Rica", "crsjo",
-        "America/Creston", "cacfq",
-        "America/Cuiaba", "brcgb",
-        "America/Curacao", "ancur",
-        "America/Danmarkshavn", "gldkshvn",
-        "America/Dawson", "cayda",
-        "America/Dawson_Creek", "caydq",
-        "America/Denver", "usden",
-        "America/Detroit", "usdet",
-        "America/Dominica", "dmdom",
-        "America/Edmonton", "caedm",
-        "America/Eirunepe", "brern",
-        "America/El_Salvador", "svsal",
-        "America/Fortaleza", "brfor",
-        "America/Glace_Bay", "caglb",
-        "America/Godthab", "glgoh",
-        "America/Goose_Bay", "cagoo",
-        "America/Grand_Turk", "tcgdt",
-        "America/Grenada", "gdgnd",
-        "America/Guadeloupe", "gpbbr",
-        "America/Guatemala", "gtgua",
-        "America/Guayaquil", "ecgye",
-        "America/Guyana", "gygeo",
-        "America/Halifax", "cahal",
-        "America/Havana", "cuhav",
-        "America/Hermosillo", "mxhmo",
-        "America/Indiana/Knox", "usknx",
-        "America/Indiana/Marengo", "usaeg",
-        "America/Indiana/Petersburg", "uswsq",
-        "America/Indiana/Tell_City", "ustel",
-        "America/Indiana/Vevay", "usinvev",
-        "America/Indiana/Vincennes", "usoea",
-        "America/Indiana/Winamac", "uswlz",
-        "America/Indianapolis", "usind",
-        "America/Inuvik", "cayev",
-        "America/Iqaluit", "caiql",
-        "America/Jamaica", "jmkin",
-        "America/Jujuy", "arjuj",
-        "America/Juneau", "usjnu",
-        "America/Kentucky/Monticello", "usmoc",
-        "America/Kralendijk", "bqkra",
-        "America/La_Paz", "bolpb",
-        "America/Lima", "pelim",
-        "America/Los_Angeles", "uslax",
-        "America/Louisville", "uslui",
-        "America/Lower_Princes", "sxphi",
-        "America/Maceio", "brmcz",
-        "America/Managua", "nimga",
-        "America/Manaus", "brmao",
-        "America/Marigot", "gpmsb",
-        "America/Martinique", "mqfdf",
-        "America/Matamoros", "mxmam",
-        "America/Mazatlan", "mxmzt",
-        "America/Mendoza", "armdz",
-        "America/Menominee", "usmnm",
-        "America/Merida", "mxmid",
-        "America/Metlakatla", "usmtm",
-        "America/Mexico_City", "mxmex",
-        "America/Miquelon", "pmmqc",
-        "America/Moncton", "camon",
-        "America/Monterrey", "mxmty",
-        "America/Montevideo", "uymvd",
-        "America/Montreal", "camtr",
-        "America/Montserrat", "msmni",
-        "America/Nassau", "bsnas",
-        "America/New_York", "usnyc",
-        "America/Nipigon", "canpg",
-        "America/Nome", "usome",
-        "America/Noronha", "brfen",
-        "America/North_Dakota/Beulah", "usxul",
-        "America/North_Dakota/Center", "usndcnt",
-        "America/North_Dakota/New_Salem", "usndnsl",
-        "America/Ojinaga", "mxoji",
-        "America/Panama", "papty",
-        "America/Pangnirtung", "capnt",
-        "America/Paramaribo", "srpbm",
-        "America/Phoenix", "usphx",
-        "America/Port_of_Spain", "ttpos",
-        "America/Port-au-Prince", "htpap",
-        "America/Porto_Velho", "brpvh",
-        "America/Puerto_Rico", "prsju",
-        "America/Rainy_River", "caffs",
-        "America/Rankin_Inlet", "cayek",
-        "America/Recife", "brrec",
-        "America/Regina", "careg",
-        "America/Resolute", "careb",
-        "America/Rio_Branco", "brrbr",
-        "America/Santa_Isabel", "mxstis",
-        "America/Santarem", "brstm",
-        "America/Santiago", "clscl",
-        "America/Santo_Domingo", "dosdq",
-        "America/Sao_Paulo", "brsao",
-        "America/Scoresbysund", "globy",
-        "America/Shiprock", "usnavajo",
-        "America/Sitka", "ussit",
-        "America/St_Barthelemy", "gpsbh",
-        "America/St_Johns", "casjf",
-        "America/St_Kitts", "knbas",
-        "America/St_Lucia", "lccas",
-        "America/St_Thomas", "vistt",
-        "America/St_Vincent", "vcsvd",
-        "America/Swift_Current", "cayyn",
-        "America/Tegucigalpa", "hntgu",
-        "America/Thule", "glthu",
-        "America/Thunder_Bay", "cathu",
-        "America/Tijuana", "mxtij",
-        "America/Toronto", "cator",
-        "America/Tortola", "vgtov",
-        "America/Vancouver", "cavan",
-        "America/Whitehorse", "cayxy",
-        "America/Winnipeg", "cawnp",
-        "America/Yakutat", "usyak",
-        "America/Yellowknife", "cayzf",
-        "Antarctica/Casey", "aqcas",
-        "Antarctica/Davis", "aqdav",
-        "Antarctica/DumontDUrville", "aqddu",
-        "Antarctica/Macquarie", "aumqi",
-        "Antarctica/Mawson", "aqmaw",
-        "Antarctica/McMurdo", "aqmcm",
-        "Antarctica/Palmer", "aqplm",
-        "Antarctica/Rothera", "aqrot",
-        "Antarctica/South_Pole", "aqams",
-        "Antarctica/Syowa", "aqsyw",
-        "Antarctica/Vostok", "aqvos",
-        "Arctic/Longyearbyen", "sjlyr",
-        "Asia/Aden", "yeade",
-        "Asia/Almaty", "kzala",
-        "Asia/Amman", "joamm",
-        "Asia/Anadyr", "rudyr",
-        "Asia/Aqtau", "kzaau",
-        "Asia/Aqtobe", "kzakx",
-        "Asia/Ashgabat", "tmasb",
-        "Asia/Baghdad", "iqbgw",
-        "Asia/Bahrain", "bhbah",
-        "Asia/Baku", "azbak",
-        "Asia/Bangkok", "thbkk",
-        "Asia/Beirut", "lbbey",
-        "Asia/Bishkek", "kgfru",
-        "Asia/Brunei", "bnbwn",
-        "Asia/Calcutta", "inccu",
-        "Asia/Choibalsan", "mncoq",
-        "Asia/Chongqing", "cnckg",
-        "Asia/Colombo", "lkcmb",
-        "Asia/Damascus", "sydam",
-        "Asia/Dhaka", "bddac",
-        "Asia/Dili", "tldil",
-        "Asia/Dubai", "aedxb",
-        "Asia/Dushanbe", "tjdyu",
-        "Asia/Gaza", "gaza",
-        "Asia/Harbin", "cnhrb",
-        "Asia/Hebron", "hebron",
-        "Asia/Hong_Kong", "hkhkg",
-        "Asia/Hovd", "mnhvd",
-        "Asia/Irkutsk", "ruikt",
-        "Asia/Jakarta", "idjkt",
-        "Asia/Jayapura", "iddjj",
-        "Asia/Jerusalem", "jeruslm",
-        "Asia/Kabul", "afkbl",
-        "Asia/Kamchatka", "rupkc",
-        "Asia/Karachi", "pkkhi",
-        "Asia/Kashgar", "cnkhg",
-        "Asia/Katmandu", "npktm",
-        "Asia/Krasnoyarsk", "rukra",
-        "Asia/Kuala_Lumpur", "mykul",
-        "Asia/Kuching", "mykch",
-        "Asia/Kuwait", "kwkwi",
-        "Asia/Macau", "momfm",
-        "Asia/Magadan", "rugdx",
-        "Asia/Makassar", "idmak",
-        "Asia/Manila", "phmnl",
-        "Asia/Muscat", "ommct",
-        "Asia/Nicosia", "cynic",
-        "Asia/Novokuznetsk", "runoz",
-        "Asia/Novosibirsk", "ruovb",
-        "Asia/Omsk", "ruoms",
-        "Asia/Oral", "kzura",
-        "Asia/Phnom_Penh", "khpnh",
-        "Asia/Pontianak", "idpnk",
-        "Asia/Pyongyang", "kpfnj",
-        "Asia/Qatar", "qadoh",
-        "Asia/Qyzylorda", "kzkzo",
-        "Asia/Rangoon", "mmrgn",
-        "Asia/Riyadh", "saruh",
-        "Asia/Saigon", "vnsgn",
-        "Asia/Sakhalin", "ruuus",
-        "Asia/Samarkand", "uzskd",
-        "Asia/Seoul", "krsel",
-        "Asia/Shanghai", "cnsha",
-        "Asia/Singapore", "sgsin",
-        "Asia/Taipei", "twtpe",
-        "Asia/Tashkent", "uztas",
-        "Asia/Tbilisi", "getbs",
-        "Asia/Tehran", "irthr",
-        "Asia/Thimphu", "btthi",
-        "Asia/Tokyo", "jptyo",
-        "Asia/Ulaanbaatar", "mnuln",
-        "Asia/Urumqi", "cnurc",
-        "Asia/Vientiane", "lavte",
-        "Asia/Vladivostok", "ruvvo",
-        "Asia/Yakutsk", "ruyks",
-        "Asia/Yekaterinburg", "ruyek",
-        "Asia/Yerevan", "amevn",
-        "Atlantic/Azores", "ptpdl",
-        "Atlantic/Bermuda", "bmbda",
-        "Atlantic/Canary", "eslpa",
-        "Atlantic/Cape_Verde", "cvrai",
-        "Atlantic/Faeroe", "fotho",
-        "Atlantic/Madeira", "ptfnc",
-        "Atlantic/Reykjavik", "isrey",
-        "Atlantic/South_Georgia", "gsgrv",
-        "Atlantic/St_Helena", "shshn",
-        "Atlantic/Stanley", "fkpsy",
-        "Australia/Adelaide", "auadl",
-        "Australia/Brisbane", "aubne",
-        "Australia/Broken_Hill", "aubhq",
-        "Australia/Currie", "aukns",
-        "Australia/Darwin", "audrw",
-        "Australia/Eucla", "aueuc",
-        "Australia/Hobart", "auhba",
-        "Australia/Lindeman", "auldc",
-        "Australia/Lord_Howe", "auldh",
-        "Australia/Melbourne", "aumel",
-        "Australia/Perth", "auper",
-        "Australia/Sydney", "ausyd",
-        "CST6CDT", "cst6cdt",
-        "EST5EDT", "est5edt",
-        "Etc/GMT", "utc",
-        "Etc/GMT+1", "utcw01",
-        "Etc/GMT+10", "utcw10",
-        "Etc/GMT+11", "utcw11",
-        "Etc/GMT+12", "utcw12",
-        "Etc/GMT+2", "utcw02",
-        "Etc/GMT+3", "utcw03",
-        "Etc/GMT+4", "utcw04",
-        "Etc/GMT+5", "utcw05",
-        "Etc/GMT+6", "utcw06",
-        "Etc/GMT+7", "utcw07",
-        "Etc/GMT+8", "utcw08",
-        "Etc/GMT+9", "utcw09",
-        "Etc/GMT-1", "utce01",
-        "Etc/GMT-10", "utce10",
-        "Etc/GMT-11", "utce11",
-        "Etc/GMT-12", "utce12",
-        "Etc/GMT-13", "utce13",
-        "Etc/GMT-14", "utce14",
-        "Etc/GMT-2", "utce02",
-        "Etc/GMT-3", "utce03",
-        "Etc/GMT-4", "utce04",
-        "Etc/GMT-5", "utce05",
-        "Etc/GMT-6", "utce06",
-        "Etc/GMT-7", "utce07",
-        "Etc/GMT-8", "utce08",
-        "Etc/GMT-9", "utce09",
-        "Etc/Unknown", "unk",
-        "Europe/Amsterdam", "nlams",
-        "Europe/Andorra", "adalv",
-        "Europe/Athens", "grath",
-        "Europe/Belgrade", "rsbeg",
-        "Europe/Berlin", "deber",
-        "Europe/Bratislava", "skbts",
-        "Europe/Brussels", "bebru",
-        "Europe/Bucharest", "robuh",
-        "Europe/Budapest", "hubud",
-        "Europe/Chisinau", "mdkiv",
-        "Europe/Copenhagen", "dkcph",
-        "Europe/Dublin", "iedub",
-        "Europe/Gibraltar", "gigib",
-        "Europe/Guernsey", "gggci",
-        "Europe/Helsinki", "fihel",
-        "Europe/Isle_of_Man", "imdgs",
-        "Europe/Istanbul", "trist",
-        "Europe/Jersey", "jesth",
-        "Europe/Kaliningrad", "rukgd",
-        "Europe/Kiev", "uaiev",
-        "Europe/Lisbon", "ptlis",
-        "Europe/Ljubljana", "silju",
-        "Europe/London", "gblon",
-        "Europe/Luxembourg", "lulux",
-        "Europe/Madrid", "esmad",
-        "Europe/Malta", "mtmla",
-        "Europe/Mariehamn", "fimhq",
-        "Europe/Minsk", "bymsq",
-        "Europe/Monaco", "mcmon",
-        "Europe/Moscow", "rumow",
-        "Europe/Oslo", "noosl",
-        "Europe/Paris", "frpar",
-        "Europe/Podgorica", "metgd",
-        "Europe/Prague", "czprg",
-        "Europe/Riga", "lvrix",
-        "Europe/Rome", "itrom",
-        "Europe/Samara", "rukuf",
-        "Europe/San_Marino", "smsai",
-        "Europe/Sarajevo", "basjj",
-        "Europe/Simferopol", "uasip",
-        "Europe/Skopje", "mkskp",
-        "Europe/Sofia", "bgsof",
-        "Europe/Stockholm", "sesto",
-        "Europe/Tallinn", "eetll",
-        "Europe/Tirane", "altia",
-        "Europe/Uzhgorod", "uauzh",
-        "Europe/Vaduz", "livdz",
-        "Europe/Vatican", "vavat",
-        "Europe/Vienna", "atvie",
-        "Europe/Vilnius", "ltvno",
-        "Europe/Volgograd", "ruvog",
-        "Europe/Warsaw", "plwaw",
-        "Europe/Zagreb", "hrzag",
-        "Europe/Zaporozhye", "uaozh",
-        "Europe/Zurich", "chzrh",
-        "Indian/Antananarivo", "mgtnr",
-        "Indian/Chagos", "iodga",
-        "Indian/Christmas", "cxxch",
-        "Indian/Cocos", "cccck",
-        "Indian/Comoro", "kmyva",
-        "Indian/Kerguelen", "tfpfr",
-        "Indian/Mahe", "scmaw",
-        "Indian/Maldives", "mvmle",
-        "Indian/Mauritius", "muplu",
-        "Indian/Mayotte", "ytmam",
-        "Indian/Reunion", "rereu",
-        "MST7MDT", "mst7mdt",
-        "Pacific/Apia", "wsapw",
-        "Pacific/Auckland", "nzakl",
-        "Pacific/Chatham", "nzcht",
-        "Pacific/Easter", "clipc",
-        "Pacific/Efate", "vuvli",
-        "Pacific/Enderbury", "kipho",
-        "Pacific/Fakaofo", "tkfko",
-        "Pacific/Fiji", "fjsuv",
-        "Pacific/Funafuti", "tvfun",
-        "Pacific/Galapagos", "ecgps",
-        "Pacific/Gambier", "pfgmr",
-        "Pacific/Guadalcanal", "sbhir",
-        "Pacific/Guam", "gugum",
-        "Pacific/Honolulu", "ushnl",
-        "Pacific/Johnston", "umjon",
-        "Pacific/Kiritimati", "kicxi",
-        "Pacific/Kosrae", "fmksa",
-        "Pacific/Kwajalein", "mhkwa",
-        "Pacific/Majuro", "mhmaj",
-        "Pacific/Marquesas", "pfnhv",
-        "Pacific/Midway", "ummdy",
-        "Pacific/Nauru", "nrinu",
-        "Pacific/Niue", "nuiue",
-        "Pacific/Norfolk", "nfnlk",
-        "Pacific/Noumea", "ncnou",
-        "Pacific/Pago_Pago", "asppg",
-        "Pacific/Palau", "pwror",
-        "Pacific/Pitcairn", "pnpcn",
-        "Pacific/Ponape", "fmpni",
-        "Pacific/Port_Moresby", "pgpom",
-        "Pacific/Rarotonga", "ckrar",
-        "Pacific/Saipan", "mpspn",
-        "Pacific/Tahiti", "pfppt",
-        "Pacific/Tarawa", "kitrw",
-        "Pacific/Tongatapu", "totbu",
-        "Pacific/Truk", "fmtkk",
-        "Pacific/Wake", "umawk",
-        "Pacific/Wallis", "wfmau",
-        "PST8PDT", "pst8pdt",
-    };
-
-    private static final String[] TYPEALIAS_COLSTRENGTH = {
-        "quarternary", "quaternary",
-    };
-
-    private static final String[] TYPEALIAS_TIMEZONE = {
-        "Africa/Asmara", "Africa/Asmera",
-        "Africa/Timbuktu", "Africa/Bamako",
-        "America/Argentina/Buenos_Aires", "America/Buenos_Aires",
-        "America/Argentina/Catamarca", "America/Catamarca",
-        "America/Argentina/ComodRivadavia", "America/Catamarca",
-        "America/Argentina/Cordoba", "America/Cordoba",
-        "America/Argentina/Jujuy", "America/Jujuy",
-        "America/Argentina/Mendoza", "America/Mendoza",
-        "America/Atikokan", "America/Coral_Harbour",
-        "America/Atka", "America/Adak",
-        "America/Ensenada", "America/Tijuana",
-        "America/Fort_Wayne", "America/Indianapolis",
-        "America/Indiana/Indianapolis", "America/Indianapolis",
-        "America/Kentucky/Louisville", "America/Louisville",
-        "America/Knox_IN", "America/Indiana/Knox",
-        "America/Porto_Acre", "America/Rio_Branco",
-        "America/Rosario", "America/Cordoba",
-        "America/Virgin", "America/St_Thomas",
-        "Asia/Ashkhabad", "Asia/Ashgabat",
-        "Asia/Chungking", "Asia/Chongqing",
-        "Asia/Dacca", "Asia/Dhaka",
-        "Asia/Ho_Chi_Minh", "Asia/Saigon",
-        "Asia/Istanbul", "Europe/Istanbul",
-        "Asia/Kathmandu", "Asia/Katmandu",
-        "Asia/Kolkata", "Asia/Calcutta",
-        "Asia/Macao", "Asia/Macau",
-        "Asia/Tel_Aviv", "Asia/Jerusalem",
-        "Asia/Thimbu", "Asia/Thimphu",
-        "Asia/Ujung_Pandang", "Asia/Makassar",
-        "Asia/Ulan_Bator", "Asia/Ulaanbaatar",
-        "Atlantic/Faroe", "Atlantic/Faeroe",
-        "Atlantic/Jan_Mayen", "Arctic/Longyearbyen",
-        "Australia/ACT", "Australia/Sydney",
-        "Australia/Canberra", "Australia/Sydney",
-        "Australia/LHI", "Australia/Lord_Howe",
-        "Australia/North", "Australia/Darwin",
-        "Australia/NSW", "Australia/Sydney",
-        "Australia/Queensland", "Australia/Brisbane",
-        "Australia/South", "Australia/Adelaide",
-        "Australia/Tasmania", "Australia/Hobart",
-        "Australia/Victoria", "Australia/Melbourne",
-        "Australia/West", "Australia/Perth",
-        "Australia/Yancowinna", "Australia/Broken_Hill",
-        "Brazil/Acre", "America/Rio_Branco",
-        "Brazil/DeNoronha", "America/Noronha",
-        "Brazil/East", "America/Sao_Paulo",
-        "Brazil/West", "America/Manaus",
-        "Canada/Atlantic", "America/Halifax",
-        "Canada/Central", "America/Winnipeg",
-        "Canada/Eastern", "America/Toronto",
-        "Canada/East-Saskatchewan", "America/Regina",
-        "Canada/Mountain", "America/Edmonton",
-        "Canada/Newfoundland", "America/St_Johns",
-        "Canada/Pacific", "America/Vancouver",
-        "Canada/Saskatchewan", "America/Regina",
-        "Canada/Yukon", "America/Whitehorse",
-        "Chile/Continental", "America/Santiago",
-        "Chile/EasterIsland", "Pacific/Easter",
-        "Cuba", "America/Havana",
-        "Egypt", "Africa/Cairo",
-        "Eire", "Europe/Dublin",
-        "EST", "Etc/GMT+5",
-        "Etc/GMT+0", "Etc/GMT",
-        "Etc/GMT0", "Etc/GMT",
-        "Etc/GMT-0", "Etc/GMT",
-        "Etc/Greenwich", "Etc/GMT",
-        "Etc/UCT", "Etc/GMT",
-        "Etc/Universal", "Etc/GMT",
-        "Etc/UTC", "Etc/GMT",
-        "Etc/Zulu", "Etc/GMT",
-        "Europe/Belfast", "Europe/London",
-        "Europe/Nicosia", "Asia/Nicosia",
-        "Europe/Tiraspol", "Europe/Chisinau",
-        "GB", "Europe/London",
-        "GB-Eire", "Europe/London",
-        "GMT", "Etc/GMT",
-        "GMT+0", "Etc/GMT",
-        "GMT0", "Etc/GMT",
-        "GMT-0", "Etc/GMT",
-        "Greenwich", "Etc/GMT",
-        "Hongkong", "Asia/Hong_Kong",
-        "HST", "Etc/GMT+10",
-        "Iceland", "Atlantic/Reykjavik",
-        "Iran", "Asia/Tehran",
-        "Israel", "Asia/Jerusalem",
-        "Jamaica", "America/Jamaica",
-        "Japan", "Asia/Tokyo",
-        "Kwajalein", "Pacific/Kwajalein",
-        "Libya", "Africa/Tripoli",
-        "Mexico/BajaNorte", "America/Tijuana",
-        "Mexico/BajaSur", "America/Mazatlan",
-        "Mexico/General", "America/Mexico_City",
-        "MST", "Etc/GMT+7",
-        "Navajo", "America/Shiprock",
-        "NZ", "Pacific/Auckland",
-        "NZ-CHAT", "Pacific/Chatham",
-        "Pacific/Chuuk", "Pacific/Truk",
-        "Pacific/Pohnpei", "Pacific/Ponape",
-        "Pacific/Samoa", "Pacific/Pago_Pago",
-        "Pacific/Yap", "Pacific/Truk",
-        "Poland", "Europe/Warsaw",
-        "Portugal", "Europe/Lisbon",
-        "PRC", "Asia/Shanghai",
-        "ROC", "Asia/Taipei",
-        "ROK", "Asia/Seoul",
-        "Singapore", "Asia/Singapore",
-        "Turkey", "Europe/Istanbul",
-        "UCT", "Etc/GMT",
-        "Universal", "Etc/GMT",
-        "US/Alaska", "America/Anchorage",
-        "US/Aleutian", "America/Adak",
-        "US/Arizona", "America/Phoenix",
-        "US/Central", "America/Chicago",
-        "US/Eastern", "America/New_York",
-        "US/East-Indiana", "America/Indianapolis",
-        "US/Hawaii", "Pacific/Honolulu",
-        "US/Indiana-Starke", "America/Indiana/Knox",
-        "US/Michigan", "America/Detroit",
-        "US/Mountain", "America/Denver",
-        "US/Pacific", "America/Los_Angeles",
-        "US/Pacific-New", "America/Los_Angeles",
-        "US/Samoa", "Pacific/Pago_Pago",
-        "UTC", "Etc/GMT",
-        "W-SU", "Europe/Moscow",
-        "Zulu", "Etc/GMT",
-    };
-}
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/.classpath b/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/.classpath
deleted file mode 100644
index 3bc2475..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/.project b/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/.project
deleted file mode 100644
index b406f25..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/.project
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>com.ibm.icu.tests</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.ManifestBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.SchemaBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.PluginNature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/.settings/org.eclipse.core.resources.prefs b/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c0..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/<project>=UTF-8
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/.settings/org.eclipse.jdt.core.prefs b/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index b237e4c..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,77 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=ignore
-org.eclipse.jdt.core.compiler.problem.deprecation=ignore
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=warning
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.7
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/.settings/org.eclipse.jdt.ui.prefs b/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/.settings/org.eclipse.jdt.ui.prefs
deleted file mode 100644
index 1c69cb6..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/.settings/org.eclipse.jdt.ui.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Thu Dec 14 11:51:01 EST 2006
-eclipse.preferences.version=1
-internal.default.compliance=default
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/META-INF/MANIFEST.MF b/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/META-INF/MANIFEST.MF
deleted file mode 100644
index 7f1de1f..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,10 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: %pluginName
-Bundle-SymbolicName: com.ibm.icu.tests
-Bundle-Version: @BUILD_VERSION@
-Bundle-Vendor: %providerName
-Fragment-Host: com.ibm.icu
-Bundle-Copyright: @COPYRIGHT@
-Require-Bundle: org.junit
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/build.properties b/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/build.properties
deleted file mode 100644
index 3edb708..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/build.properties
+++ /dev/null
@@ -1,17 +0,0 @@
-###############################################################################
-# Copyright (c) 2000, 2011 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     IBM Corporation - initial API and implementation
-###############################################################################
-source.. = src/
-output.. = bin/
-bin.includes = .,\
-               about.html,\
-               about_files/,\
-               plugin.properties,\
-               META-INF/
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/plugin.properties b/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/plugin.properties
deleted file mode 100644
index 143ebca..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu.tests/plugin.properties
+++ /dev/null
@@ -1,12 +0,0 @@
-###############################################################################
-# Copyright (c) 2011 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials 
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     IBM Corporation - initial API and implementation
-###############################################################################
-pluginName = International Components for Unicode for Java (ICU4J) Tests
-providerName = IBM Corporation
\ No newline at end of file
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu/.classpath b/icu4j/eclipse-build/plugins.template/com.ibm.icu/.classpath
deleted file mode 100644
index 3bc2475..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu/.project b/icu4j/eclipse-build/plugins.template/com.ibm.icu/.project
deleted file mode 100644
index e73714f..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu/.project
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>com.ibm.icu</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.pde.ManifestBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.SchemaBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-		<nature>org.eclipse.pde.PluginNature</nature>
-	</natures>
-</projectDescription>
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu/.settings/org.eclipse.core.resources.prefs b/icu4j/eclipse-build/plugins.template/com.ibm.icu/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c0..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/<project>=UTF-8
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu/.settings/org.eclipse.jdt.core.prefs b/icu4j/eclipse-build/plugins.template/com.ibm.icu/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index a8076c5..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,76 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=ignore
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=warning
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.7
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu/.settings/org.eclipse.jdt.ui.prefs b/icu4j/eclipse-build/plugins.template/com.ibm.icu/.settings/org.eclipse.jdt.ui.prefs
deleted file mode 100644
index 5693f2f..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu/.settings/org.eclipse.jdt.ui.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Thu Dec 14 11:50:17 EST 2006
-eclipse.preferences.version=1
-internal.default.compliance=default
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu/META-INF/MANIFEST.MF b/icu4j/eclipse-build/plugins.template/com.ibm.icu/META-INF/MANIFEST.MF
deleted file mode 100644
index 1859834..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,29 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: %pluginName
-Bundle-SymbolicName: com.ibm.icu; singleton:=true
-Bundle-Version: @BUILD_VERSION@
-Bundle-Vendor: %providerName
-Bundle-Localization: plugin
-Bundle-Copyright: @COPYRIGHT@
-Export-Package: com.ibm.icu.lang;base=true;full=true;version="@IMPL_VERSION@",
- com.ibm.icu.math;base=true;full=true;version="@IMPL_VERSION@",
- com.ibm.icu.text;base=true;full=true;version="@IMPL_VERSION@",
- com.ibm.icu.util;base=true;full=true;version="@IMPL_VERSION@",
- com.ibm.icu.impl;x-internal:=true,
- com.ibm.icu.impl.data;x-internal:=true,
- com.ibm.icu.impl.data.icudt@DATA_VERSION_NUMBER@b;x-internal:=true,
- com.ibm.icu.impl.data.icudt@DATA_VERSION_NUMBER@b.brkitr;x-internal:=true,
- com.ibm.icu.impl.data.icudt@DATA_VERSION_NUMBER@b.coll;x-internal:=true,
- com.ibm.icu.impl.data.icudt@DATA_VERSION_NUMBER@b.curr;x-internal:=true,
- com.ibm.icu.impl.data.icudt@DATA_VERSION_NUMBER@b.lang;x-internal:=true,
- com.ibm.icu.impl.data.icudt@DATA_VERSION_NUMBER@b.rbnf;x-internal:=true,
- com.ibm.icu.impl.data.icudt@DATA_VERSION_NUMBER@b.region;x-internal:=true,
- com.ibm.icu.impl.data.icudt@DATA_VERSION_NUMBER@b.translit;x-internal:=true,
- com.ibm.icu.impl.data.icudt@DATA_VERSION_NUMBER@b.zone;x-internal:=true,
- com.ibm.icu.impl.duration;x-internal:=true,
- com.ibm.icu.impl.locale;x-internal:=true
-Eclipse-LazyStart: true
-Bundle-RequiredExecutionEnvironment: JavaSE-1.7
-Bundle-ClassPath: icu-data.jar,.
-Eclipse-ExtensibleAPI: true
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu/build.properties b/icu4j/eclipse-build/plugins.template/com.ibm.icu/build.properties
deleted file mode 100644
index 8c108f2..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu/build.properties
+++ /dev/null
@@ -1,19 +0,0 @@
-###############################################################################
-# Copyright (c) 2000, 2008 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     IBM Corporation - initial API and implementation
-###############################################################################
-source.. = src/
-output.. = bin/
-src.includes = about.html,\
-               about_files/
-bin.includes = .,\
-               about.html,\
-               about_files/,\
-               plugin.properties,\
-               META-INF/
diff --git a/icu4j/eclipse-build/plugins.template/com.ibm.icu/plugin.properties b/icu4j/eclipse-build/plugins.template/com.ibm.icu/plugin.properties
deleted file mode 100644
index 9fe7037..0000000
--- a/icu4j/eclipse-build/plugins.template/com.ibm.icu/plugin.properties
+++ /dev/null
@@ -1,12 +0,0 @@
-###############################################################################
-# Copyright (c) 2000, 2008 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials 
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-# 
-# Contributors:
-#     IBM Corporation - initial API and implementation
-###############################################################################
-pluginName = International Components for Unicode for Java (ICU4J)
-providerName = IBM Corporation
\ No newline at end of file
