Project import
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..ca9a3da
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,31 @@
+#
+#    Copyright (c) 2010-2011 Nest, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the makefile for the International Components for
+#      Unicode (ICU) library.
+#
+#      Per "icu/readme.html", the correct way to cross-compile ICU is
+#      is build first a host version and then to build a target version
+#      and to point the target version at that host version.
+#
+
+.NOTPARALLEL:
+
+include pre.mak
+
+SubMakefiles  = Makefile.host
+
+ifneq ($(BUILD_FEATURE_SIMULATOR),1)
+SubMakefiles += Makefile.target
+endif
+
+include post.mak
diff --git a/Makefile.common b/Makefile.common
new file mode 100644
index 0000000..fc91f85
--- /dev/null
+++ b/Makefile.common
@@ -0,0 +1,58 @@
+#
+#    Copyright (c) 2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is a make file header defining macros and targets
+#      for customizing ICU on a per-build basis.
+#
+
+ICUDataConfSUFFIX		:= local.mk
+
+ICUDataConfSTEMS		:= brkitr/brk	 \
+				   brkitr/brs	 \
+				   coll/col	 \
+				   curr/res	 \
+				   lang/res	 \
+				   locales/res	 \
+				   misc/misc	 \
+				   rbnf/rbnf	 \
+				   region/res	 \
+				   sprep/sprep	 \
+				   translit/trns \
+				   mappings/ucm	 \
+				   zone/res
+
+ICUDataConfFiles		= $(addsuffix $(ICUDataConfSUFFIX),$(ICUDataConfSTEMS))
+
+ICUDataConfSourceDir		:= ./configs
+
+ICUDataConfSourcePaths		= $(addprefix $(call Slashify,$(ICUDataConfSourceDir)),$(ICUDataConfFiles))
+
+ICUDataConfBuildDir		= $(BuildDirectory)/data
+
+ICUDataConfBuildPaths		= $(addprefix $(call Slashify,$(ICUDataConfBuildDir)),$(ICUDataConfFiles))
+
+ICUDataConfMaybeSourcePaths 	= $(wildcard $(ICUDataConfSourcePaths))
+
+ICUDataConfMaybeFiles		= $(subst $(call Slashify,$(ICUDataConfSourceDir)),,$(ICUDataConfMaybeSourcePaths))
+
+ICUDataConfMaybeBuildPaths	= $(addprefix $(call Slashify,$(ICUDataConfBuildDir)),$(ICUDataConfMaybeFiles))
+
+$(ICUDataConfMaybeBuildPaths): $(ICUDataConfBuildDir)/%: $(ICUDataConfSourceDir)/%
+	$(Echo) "Creating \"$(call GenerateBuildRootEllipsedPath,$(@D))\""
+	$(Verbose)$(MKDIR) $(MKDIRFLAGS) $(@D)
+	$(copy-result)
+
+# Ensure that the static implicit pattern rule above doesn't become
+# the default target goal. Instead, use the usual default, 'all'.
+
+.DEFAULT_GOAL           := all
+
diff --git a/Makefile.host b/Makefile.host
new file mode 100644
index 0000000..8f447ce
--- /dev/null
+++ b/Makefile.host
@@ -0,0 +1,122 @@
+#
+#    Copyright (c) 2010-2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the host make file for the International
+#      Components for Unicode (ICU) library.
+#
+
+# To cross-compile, ICU needs to be bootstrapped for whatever the
+# native build host is. In our environment, that's the simulator.  At
+# some point in the future, we should tease apart truly building for
+# the simulator and just building host-native stuff to support a build
+# target.
+
+#TODO QUESTION what is this?  diamondsim // diamond3sim?
+
+ifneq ($(BUILD_FEATURE_SIMULATOR),1)
+override BuildProduct	:= diamondsim
+SaveBuildMode		:= $(BuildMode)
+override BuildMode	:= snapshot
+endif
+
+include pre.mak
+include ./Makefile.common
+
+PackageName		:= icu
+
+PackageExtension	:= tar.gz
+PackageSeparator	:= -
+
+PackagePatchArgs	:= -p1
+
+PackageArchive		:= $(PackageName).$(PackageExtension)
+PackageSourceDir	:= $(PackageName)
+
+PackageBuildMakefile	= $(call GenerateBuildPaths,Makefile)
+
+CleanPaths		+= $(PackageLicenseFile)
+
+all: $(PackageDefaultGoal)
+
+# Generate the package license contents.
+
+$(PackageSourceDir)/license.html: source
+
+$(PackageLicenseFile): $(PackageSourceDir)/license.html
+	$(copy-result)
+
+# Extract the source from the archive and apply patches, if any.
+
+$(PackageSourceDir): $(PackageArchive) $(PackagePatchPaths)
+	$(expand-and-patch-package)
+
+# Prepare the sources.
+
+.PHONY: source
+source: | $(PackageSourceDir)
+
+# Patch the sources, if necessary.
+
+.PHONY: patch
+patch: source
+
+# Generate the package build makefile.
+
+$(PackageBuildMakefile): | $(PackageSourceDir) $(BuildDirectory) $(ResultDirectory)
+	$(Verbose)cd $(BuildDirectory) && \
+	INSTALL="$(INSTALL) $(INSTALLFLAGS)" \
+	$(CURDIR)/$(PackageSourceDir)/source/configure \
+	--prefix=/usr \
+	--sysconfdir=/etc \
+	--localstatedir=/var \
+	--disable-extras \
+	--disable-icuio \
+	--disable-layout \
+	--disable-tests \
+	--disable-samples
+
+
+# Configure the source for building.
+
+$(ICUDataConfMaybeBuildPaths): | $(BuildDirectory)
+
+.PHONY: configure
+configure: source $(ICUDataConfMaybeBuildPaths) $(PackageBuildMakefile)
+
+# Build the source.
+#
+# We have to unset MAKEFLAGS since they confuse the package build otherwise.
+
+.PHONY: build
+build: configure
+	$(Verbose)unset MAKEFLAGS && \
+	$(MAKE) $(JOBSFLAG) -C $(BuildDirectory) all
+
+# Stage the build to a temporary installation area.
+#
+# We have to unset MAKEFLAGS since they confuse the package build otherwise.
+
+.PHONY: stage
+stage: build | $(ResultDirectory)
+	$(Verbose)unset MAKEFLAGS && \
+	$(MAKE) $(JOBSFLAG) -C $(BuildDirectory) DESTDIR=$(ResultDirectory) install
+
+clean:
+	$(Verbose)$(RM) $(RMFLAGS) -r $(PackageSourceDir)
+	$(Verbose)$(RM) $(RMFLAGS) -r $(BuildDirectory)
+	$(Verbose)$(RM) $(RMFLAGS) -r $(ResultDirectory)
+
+include post.mak
+
+ifneq ($(BUILD_FEATURE_SIMULATOR),1)
+override BuildMode	:= $(SaveBuildMode)
+endif
diff --git a/Makefile.target b/Makefile.target
new file mode 100644
index 0000000..38dedf9
--- /dev/null
+++ b/Makefile.target
@@ -0,0 +1,116 @@
+#
+#    Copyright (c) 2010-2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the target make file for the International
+#      Components for Unicode (ICU) library.
+#
+
+include pre.mak
+include ./Makefile.common
+
+PackageName		:= icu
+
+PackageExtension	:= tar.gz
+PackageSeparator	:= -
+
+PackagePatchArgs	:= -p1
+
+PackageArchive		:= $(PackageName).$(PackageExtension)
+PackageSourceDir	:= $(PackageName)
+
+PackageBuildMakefile	= $(call GenerateBuildPaths,Makefile)
+
+# Find where the native host boot strap build is at. This is required
+# to cross-compile ICU.
+#
+# This is beyond ugly but expedient.
+
+ICUHostBuildPath	:= $(call Slashify,$(CURDIR))$(call Deslashify,$(dir $(firstword $(shell find $(BuildBaseDirectory)/Makefile.host -type f -name "icudefs.mk"))))
+
+CleanPaths		+= $(PackageLicenseFile)
+
+all: $(PackageDefaultGoal)
+
+# Generate the package license contents.
+
+$(PackageSourceDir)/license.html: source
+
+$(PackageLicenseFile): $(PackageSourceDir)/license.html
+	$(copy-result)
+
+# Extract the source from the archive and apply patches, if any.
+
+$(PackageSourceDir): $(PackageArchive) $(PackagePatchPaths)
+	$(expand-and-patch-package)
+
+# Prepare the sources.
+
+.PHONY: source
+source: | $(PackageSourceDir)
+
+# Patch the sources, if necessary.
+
+.PHONY: patch
+patch: source
+
+# Generate the package build makefile.
+
+$(PackageBuildMakefile): | $(PackageSourceDir) $(BuildDirectory) $(ResultDirectory) $(ICUHostBuildPath)
+	$(Verbose)cd $(BuildDirectory) && \
+	$(CURDIR)/$(PackageSourceDir)/source/configure \
+	CC="$(filter-out $(TOOLCHAIN_EXTRA_CFLAGS),$(CC))" CXX="$(filter-out $(TOOLCHAIN_EXTRA_CFLAGS),$(CXX))" AR=$(AR) NM=$(NM) RANLIB=$(RANLIB) STRIP=$(STRIP) \
+	INSTALL="$(INSTALL) $(INSTALLFLAGS)" \
+	CPPFLAGS="$(CPPOPTFLAGS)" \
+	--build=$(HostTuple) \
+	--host=$(TargetTuple) \
+	--with-cross-build=$(ICUHostBuildPath) \
+	--prefix=/usr \
+	--sysconfdir=/etc \
+	--localstatedir=/var \
+	--disable-extras \
+	--disable-icuio \
+	--disable-layout \
+	--disable-tests \
+	--disable-samples
+
+
+# Configure the source for building.
+
+$(ICUDataConfMaybeBuildPaths): | $(BuildDirectory)
+
+.PHONY: configure
+configure: source $(ICUDataConfMaybeBuildPaths) $(PackageBuildMakefile)
+
+# Build the source.
+#
+# We have to unset MAKEFLAGS since they confuse the package build otherwise.
+
+.PHONY: build
+build: configure
+	$(Verbose)unset MAKEFLAGS && \
+	$(MAKE) $(JOBSFLAG) -C $(BuildDirectory) all
+
+# Stage the build to a temporary installation area.
+#
+# We have to unset MAKEFLAGS since they confuse the package build otherwise.
+
+.PHONY: stage
+stage: build | $(ResultDirectory)
+	$(Verbose)unset MAKEFLAGS && \
+	$(MAKE) $(JOBSFLAG) -C $(BuildDirectory) DESTDIR=$(ResultDirectory) install
+
+clean:
+	$(Verbose)$(RM) $(RMFLAGS) -r $(PackageSourceDir)
+	$(Verbose)$(RM) $(RMFLAGS) -r $(BuildDirectory)
+	$(Verbose)$(RM) $(RMFLAGS) -r $(ResultDirectory)
+
+include post.mak
diff --git a/configs/brkitr/brklocal.mk b/configs/brkitr/brklocal.mk
new file mode 100644
index 0000000..892b88f
--- /dev/null
+++ b/configs/brkitr/brklocal.mk
@@ -0,0 +1,16 @@
+#
+#    Copyright (c) 2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the vendor- and site-specific configuration for
+#      ICU.
+#
+
diff --git a/configs/brkitr/brslocal.mk b/configs/brkitr/brslocal.mk
new file mode 100644
index 0000000..892b88f
--- /dev/null
+++ b/configs/brkitr/brslocal.mk
@@ -0,0 +1,16 @@
+#
+#    Copyright (c) 2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the vendor- and site-specific configuration for
+#      ICU.
+#
+
diff --git a/configs/coll/collocal.mk b/configs/coll/collocal.mk
new file mode 100644
index 0000000..f8ffe5b
--- /dev/null
+++ b/configs/coll/collocal.mk
@@ -0,0 +1,17 @@
+#
+#    Copyright (c) 2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the vendor- and site-specific configuration for
+#      ICU.
+#
+
+COLLATION_SOURCE = en_US.txt en_CA.txt es_US.txt es.txt es_MX.txt fr_CA.txt fr.txt
diff --git a/configs/curr/reslocal.mk b/configs/curr/reslocal.mk
new file mode 100644
index 0000000..892b88f
--- /dev/null
+++ b/configs/curr/reslocal.mk
@@ -0,0 +1,16 @@
+#
+#    Copyright (c) 2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the vendor- and site-specific configuration for
+#      ICU.
+#
+
diff --git a/configs/lang/reslocal.mk b/configs/lang/reslocal.mk
new file mode 100644
index 0000000..892b88f
--- /dev/null
+++ b/configs/lang/reslocal.mk
@@ -0,0 +1,16 @@
+#
+#    Copyright (c) 2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the vendor- and site-specific configuration for
+#      ICU.
+#
+
diff --git a/configs/locales/reslocal.mk b/configs/locales/reslocal.mk
new file mode 100644
index 0000000..b79ca56
--- /dev/null
+++ b/configs/locales/reslocal.mk
@@ -0,0 +1,17 @@
+#
+#    Copyright (c) 2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the vendor- and site-specific configuration for
+#      ICU.
+#
+
+GENRB_SOURCE = en_US.txt en_CA.txt es_US.txt es.txt es_MX.txt fr_CA.txt fr.txt
diff --git a/configs/mappings/ucmlocal.mk b/configs/mappings/ucmlocal.mk
new file mode 100644
index 0000000..892b88f
--- /dev/null
+++ b/configs/mappings/ucmlocal.mk
@@ -0,0 +1,16 @@
+#
+#    Copyright (c) 2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the vendor- and site-specific configuration for
+#      ICU.
+#
+
diff --git a/configs/misc/misclocal.mk b/configs/misc/misclocal.mk
new file mode 100644
index 0000000..892b88f
--- /dev/null
+++ b/configs/misc/misclocal.mk
@@ -0,0 +1,16 @@
+#
+#    Copyright (c) 2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the vendor- and site-specific configuration for
+#      ICU.
+#
+
diff --git a/configs/rbnf/rbnflocal.mk b/configs/rbnf/rbnflocal.mk
new file mode 100644
index 0000000..892b88f
--- /dev/null
+++ b/configs/rbnf/rbnflocal.mk
@@ -0,0 +1,16 @@
+#
+#    Copyright (c) 2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the vendor- and site-specific configuration for
+#      ICU.
+#
+
diff --git a/configs/region/reslocal.mk b/configs/region/reslocal.mk
new file mode 100644
index 0000000..e946b61
--- /dev/null
+++ b/configs/region/reslocal.mk
@@ -0,0 +1,17 @@
+#
+#    Copyright (c) 2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the vendor- and site-specific configuration for
+#      ICU.
+#
+
+REGION_SOURCE = en.txt es.txt fr.txt
diff --git a/configs/sprep/spreplocal.mk b/configs/sprep/spreplocal.mk
new file mode 100644
index 0000000..892b88f
--- /dev/null
+++ b/configs/sprep/spreplocal.mk
@@ -0,0 +1,16 @@
+#
+#    Copyright (c) 2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the vendor- and site-specific configuration for
+#      ICU.
+#
+
diff --git a/configs/translit/trnslocal.mk b/configs/translit/trnslocal.mk
new file mode 100644
index 0000000..da481f8
--- /dev/null
+++ b/configs/translit/trnslocal.mk
@@ -0,0 +1,17 @@
+#
+#    Copyright (c) 2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the vendor- and site-specific configuration for
+#      ICU.
+#
+
+ TRANLIST_SOURCE = el.txt en.txt
diff --git a/configs/zone/reslocal.mk b/configs/zone/reslocal.mk
new file mode 100644
index 0000000..d3d63c4
--- /dev/null
+++ b/configs/zone/reslocal.mk
@@ -0,0 +1,17 @@
+#
+#    Copyright (c) 2012 Nest Labs, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the vendor- and site-specific configuration for
+#      ICU.
+#
+
+ZONE_SOURCE = en_CA.txt en.txt es.txt fr.txt fr_CA.txt
diff --git a/icu.patches/icu-00.description b/icu.patches/icu-00.description
new file mode 100644
index 0000000..f6721ab
--- /dev/null
+++ b/icu.patches/icu-00.description
@@ -0,0 +1 @@
+This patch changes gcc assembler syntax to use % not @; % works for both x86 and ARM
diff --git a/icu.patches/icu-00.patch b/icu.patches/icu-00.patch
new file mode 100644
index 0000000..b7237c0
--- /dev/null
+++ b/icu.patches/icu-00.patch
@@ -0,0 +1,23 @@
+diff -aruN a/source/tools/toolutil/pkg_genc.c b/source/tools/toolutil/pkg_genc.c
+--- a/source/tools/toolutil/pkg_genc.c	2010-04-28 08:27:46.000000000 -0700
++++ b/source/tools/toolutil/pkg_genc.c	2010-10-01 12:55:24.850893589 -0700
+@@ -1,5 +1,5 @@
+ /******************************************************************************
+- *   Copyright (C) 2009, International Business Machines
++ *   Copyright (C) 2009-2010, International Business Machines
+  *   Corporation and others.  All Rights Reserved.
+  *******************************************************************************
+  */
+@@ -118,10 +118,10 @@
+ } assemblyHeader[] = {
+     {"gcc",
+         ".globl %s\n"
+-        "\t.section .note.GNU-stack,\"\",@progbits\n"
++        "\t.section .note.GNU-stack,\"\",%%progbits\n"
+         "\t.section .rodata\n"
+         "\t.align 8\n" /* Either align 8 bytes or 2^8 (256) bytes. 8 bytes is needed. */
+-        "\t.type %s,@object\n"
++        "\t.type %s,%%object\n"
+         "%s:\n\n",
+ 
+         ".long ","",HEX_0X
diff --git a/icu.patches/icu-00.url b/icu.patches/icu-00.url
new file mode 100644
index 0000000..a553fa8
--- /dev/null
+++ b/icu.patches/icu-00.url
@@ -0,0 +1 @@
+https://bugs.icu-project.org/trac/changeset/28107
diff --git a/icu.patches/icu-50.description b/icu.patches/icu-50.description
new file mode 100644
index 0000000..6050fa0
--- /dev/null
+++ b/icu.patches/icu-50.description
@@ -0,0 +1 @@
+This patch ensures a link against the static libgcc is made to resolve a hidden ARM-only assembly-level primitive symbol.
diff --git a/icu.patches/icu-50.patch b/icu.patches/icu-50.patch
new file mode 100644
index 0000000..dadd6cf
--- /dev/null
+++ b/icu.patches/icu-50.patch
@@ -0,0 +1,12 @@
+diff -aruN a/source/common/Makefile.in b/source/common/Makefile.in
+--- a/source/common/Makefile.in	2010-09-30 17:53:44.194447128 -0700
++++ b/source/common/Makefile.in	2010-04-28 08:27:40.000000000 -0700
+@@ -192,7 +192,7 @@
+ 
+ ifneq ($(ENABLE_SHARED),)
+ $(SHARED_OBJECT): $(OBJECTS) $(SO_VERSION_DATA)
+-	$(SHLIB.cc) $(LD_SONAME) $(OUTOPT)$@ $^ $(LIBS)
++	$(SHLIB.cc) $(LD_SONAME) $(OUTOPT)$@ $^ $(LIBS) -lgcc
+ 
+ ifeq ($(OS390BATCH),1)
+ $(BATCH_TARGET):$(OBJECTS)
diff --git a/icu.patches/icu-51.description b/icu.patches/icu-51.description
new file mode 100644
index 0000000..d79b67d
--- /dev/null
+++ b/icu.patches/icu-51.description
@@ -0,0 +1 @@
+This patch adds support for applying ICU customizations on a per-build basis rather than on a per-source basis.
diff --git a/icu.patches/icu-51.patch b/icu.patches/icu-51.patch
new file mode 100644
index 0000000..f9fd8d7
--- /dev/null
+++ b/icu.patches/icu-51.patch
@@ -0,0 +1,110 @@
+diff -aruN a/source/data/Makefile.in b/source/data/Makefile.in
+--- a/source/data/Makefile.in	2010-04-28 08:28:50.000000000 -0700
++++ b/source/data/Makefile.in	2012-04-26 10:00:26.283892893 -0700
+@@ -66,6 +66,8 @@
+ OUTDIR=$(top_builddir)/data/out
+ endif
+ 
++CONFDIR=$(top_builddir)/data
++
+ OUTTMPDIR=$(OUTDIR)/tmp
+ MAINBUILDDIR=$(OUTDIR)/build
+ BUILDDIR=$(MAINBUILDDIR)/$(ICUDATA_PLATFORM_NAME)
+@@ -73,24 +75,35 @@
+ LOCSRCDIR=$(SRCDATADIR)/locales
++LOCCONFDIR=$(CONFDIR)/locales
+ CURRSRCDIR=$(SRCDATADIR)/curr
+ CURRBLDDIR=$(BUILDDIR)/curr
++CURRCONFDIR=$(CONFDIR)/curr
+ LANGSRCDIR=$(SRCDATADIR)/lang
+ LANGBLDDIR=$(BUILDDIR)/lang
++LANGCONFDIR=$(CONFDIR)/lang
+ REGIONSRCDIR=$(SRCDATADIR)/region
+ REGIONBLDDIR=$(BUILDDIR)/region
++REGIONCONFDIR=$(CONFDIR)/region
+ ZONESRCDIR=$(SRCDATADIR)/zone
+ ZONEBLDDIR=$(BUILDDIR)/zone
++ZONECONFDIR=$(CONFDIR)/zone
+ COLSRCDIR=$(SRCDATADIR)/coll
+ COLBLDDIR=$(BUILDDIR)/coll
++COLCONFDIR=$(CONFDIR)/coll
+ RBNFSRCDIR=$(SRCDATADIR)/rbnf
+ RBNFBLDDIR=$(BUILDDIR)/rbnf
++RBNFCONFDIR=$(CONFDIR)/rbnc
+ TRANSLITSRCDIR=$(SRCDATADIR)/translit
+ TRANSLITBLDDIR=$(BUILDDIR)/translit
++TRANSLITCONFDIR=$(CONFDIR)/translit
+ MISCSRCDIR=$(SRCDATADIR)/misc
++MISCCONFDIR=$(CONFDIR)/misc
+ BRKSRCDIR=$(SRCDATADIR)/brkitr
+ BRKBLDDIR=$(BUILDDIR)/brkitr
+-MISCSRCDIR=$(SRCDATADIR)/misc
++BRKCONFDIR=$(CONFDIR)/brkitr
+ UCMSRCDIR=$(SRCDATADIR)/mappings
++UCMCONFDIR=$(CONFDIR)/mappings
+ SPREPSRCDIR=$(SRCDATADIR)/sprep
++SPREPCONFDIR=$(CONFDIR)/sprep
+ COMINCDIR=$(top_srcdir)/common/unicode
+ SRCLISTDEPS=Makefile $(srcdir)/Makefile.in
+ BUILD_DIRS=$(OUTDIR) $(MAINBUILDDIR) $(BUILDDIR) $(CURRBLDDIR) $(LANGBLDDIR) $(REGIONBLDDIR) $(ZONEBLDDIR) $(BRKBLDDIR) $(COLBLDDIR) $(RBNFBLDDIR) $(TRANSLITBLDDIR) $(OUTTMPDIR) $(OUTTMPDIR_390STUB) $(OUTTMPDIR)/$(CURR_TREE) $(OUTTMPDIR)/$(LANG_TREE) $(OUTTMPDIR)/$(REGION_TREE) $(OUTTMPDIR)/$(ZONE_TREE) $(OUTTMPDIR)/$(COLLATION_TREE) $(OUTTMPDIR)/$(RBNF_TREE) $(OUTTMPDIR)/$(TRANSLIT_TREE) $(OUTTMPDIR)/$(BREAK_TREE)
+@@ -231,7 +243,7 @@
+ ## BRK files
+ BREAK_TREE=brkitr
+ -include $(BRKSRCDIR)/brkfiles.mk
+--include $(BRKSRCDIR)/brklocal.mk
++-include $(BRKCONFDIR)/brklocal.mk
+ ALL_BRK_SOURCE= $(BRK_SOURCE) $(BRK_SOURCE_LOCAL)
+ BRK_FILES_SHORT=$(ALL_BRK_SOURCE:%.txt=$(BREAK_TREE)/%.brk)
+ BRK_FILES=$(ALL_BRK_SOURCE:%.txt=$(BRKBLDDIR)/%.brk)
+@@ -255,7 +267,7 @@
+ -include $(UCMSRCDIR)/ucmcore.mk
+ -include $(UCMSRCDIR)/ucmfiles.mk
+ -include $(UCMSRCDIR)/ucmebcdic.mk
+--include $(UCMSRCDIR)/ucmlocal.mk
++-include $(UCMCONFDIR)/ucmlocal.mk
+ ALL_UCM_SOURCE=ibm-37_P100-1995.ucm ibm-1047_P100-1995.ucm $(UCM_SOURCE_CORE) $(UCM_SOURCE_FILES) $(UCM_SOURCE_EBCDIC) $(UCM_SOURCE_LOCAL)
+ UCM_FILES = $(ALL_UCM_SOURCE:%=$(SRCDATADIR)/%)
+ CNV_FILES = $(ALL_UCM_SOURCE:%.ucm=$(BUILDDIR)/%.cnv)
+@@ -274,15 +286,15 @@
+ -include $(COLSRCDIR)/colfiles.mk
+ -include $(RBNFSRCDIR)/rbnffiles.mk
+ -include $(TRANSLITSRCDIR)/trnsfiles.mk
+--include $(LOCSRCDIR)/reslocal.mk
+--include $(CURRSRCDIR)/reslocal.mk
+--include $(LANGSRCDIR)/reslocal.mk
+--include $(REGIONSRCDIR)/reslocal.mk
+--include $(ZONESRCDIR)/reslocal.mk
+--include $(COLSRCDIR)/collocal.mk
+--include $(BRKSRCDIR)/brslocal.mk
+--include $(RBNFSRCDIR)/rbnflocal.mk
+--include $(TRANSLITSRCDIR)/trnslocal.mk
++-include $(LOCCONFDIR)/reslocal.mk
++-include $(CURRCONFDIR)/reslocal.mk
++-include $(LANGCONFDIR)/reslocal.mk
++-include $(REGIONCONFDIR)/reslocal.mk
++-include $(ZONECONFDIR)/reslocal.mk
++-include $(COLCONFDIR)/collocal.mk
++-include $(BRKCONFDIR)/brslocal.mk
++-include $(RBNFCONFDIR)/rbnflocal.mk
++-include $(TRANSLITCONFDIR)/trnslocal.mk
+ ifdef GENRB_SOURCE
+ RES_SRC= root.txt $(GENRB_SOURCE) $(GENRB_ALIAS_SOURCE) $(GENRB_SOURCE_LOCAL) $(GENRB_ALIAS_SOURCE_LOCAL)
+ RES_SRC_FILES = $(RES_SRC:%=$(LOCSRCDIR)/%)
+@@ -327,7 +339,7 @@
+ 
+ ## MISC files
+ -include $(MISCSRCDIR)/miscfiles.mk
+--include $(MISCSRCDIR)/misclocal.mk
++-include $(MISCCONFDIR)/misclocal.mk
+ MSC_SOURCE= $(MISC_SOURCE) $(MISC_SOURCE_LOCAL)
+ MSC_SRC_FILES=$(MSC_SOURCE:%=$(MISCSRCDIR)/%)
+ 
+@@ -396,7 +408,7 @@
+ 
+ ## SPP files
+ -include $(SPREPSRCDIR)/sprepfiles.mk
+--include $(SPREPSRCDIR)/spreplocal.mk
++-include $(SPREPCONFDIR)/spreplocal.mk
+ ALL_SPREP_SOURCE=$(SPREP_SOURCE) $(SPREP_SOURCE_LOCAL)
+ SPREP_FILES = $(ALL_SPREP_SOURCE:%.txt=$(BUILDDIR)/%.spp)
+ SPREP_FILES_SHORT = $(ALL_SPREP_SOURCE:%.txt=%.spp)
diff --git a/icu.patches/icu-52.description b/icu.patches/icu-52.description
new file mode 100644
index 0000000..b4d6f94
--- /dev/null
+++ b/icu.patches/icu-52.description
@@ -0,0 +1 @@
+This patch fixes the ABI compability issue when compiling with hard floating point ABI option on ARM target
diff --git a/icu.patches/icu-52.patch b/icu.patches/icu-52.patch
new file mode 100644
index 0000000..d05cd6a
--- /dev/null
+++ b/icu.patches/icu-52.patch
@@ -0,0 +1,24 @@
+--- icu/source/tools/toolutil/pkg_genc.c	2014-06-13 03:17:39.764309319 -0700
++++ icu_new/source/tools/toolutil/pkg_genc.c	2014-06-11 01:20:27.551743424 -0700
+@@ -117,6 +117,12 @@
+     int8_t      hexType; /* HEX_0X or HEX_0h */
+ } assemblyHeader[] = {
+     {"gcc",
++
++		"#ifdef __ARM_PCS_VFP\n"
++		".fpu vfpv3\n"
++		".eabi_attribute Tag_ABI_VFP_args, 1\n"
++		".eabi_attribute Tag_ABI_HardFP_use, 3\n"
++		"#endif\n"
+         ".globl %s\n"
+         "\t.section .note.GNU-stack,\"\",%%progbits\n"
+         "\t.section .rodata\n"
+@@ -249,7 +255,7 @@
+         exit(U_FILE_ACCESS_ERROR);
+     }
+ 
+-    getOutFilename(filename, destdir, bufferStr, entry, ".s", optFilename);
++    getOutFilename(filename, destdir, bufferStr, entry, ".S", optFilename);
+     out=T_FileStream_open(bufferStr, "w");
+     if(out==NULL) {
+         fprintf(stderr, "genccode: unable to open output file %s\n", bufferStr);
diff --git a/icu.patches/icu-53.description b/icu.patches/icu-53.description
new file mode 100644
index 0000000..67ba793
--- /dev/null
+++ b/icu.patches/icu-53.description
@@ -0,0 +1 @@
+Removing CC define that that breaks distcc
diff --git a/icu.patches/icu-53.patch b/icu.patches/icu-53.patch
new file mode 100644
index 0000000..87e8af8
--- /dev/null
+++ b/icu.patches/icu-53.patch
@@ -0,0 +1,11 @@
+--- a/source/tools/icuinfo/Makefile.in
++++ b/source/tools/icuinfo/Makefile.in
+@@ -36,7 +36,7 @@ DEPS = $(OBJECTS:.o=.d)
+ 
+ ICUINFO_OPTS=-i ../../data/out/build/$(ICUDATA_PLATFORM_NAME)
+ 
+-CPPFLAGS+=  -DU_PLATFORM=\"@platform@\"  -DU_BUILD=\"@build@\" -DU_HOST=\"@host@\" -DU_CC=\"@CC@\" -DU_CXX=\"@CXX@\"
++CPPFLAGS+=  -DU_PLATFORM=\"@platform@\"  -DU_BUILD=\"@build@\" -DU_HOST=\"@host@\"
+ # -DENABLE_RELEASE=@ENABLE_RELEASE@ -DENABLE_DEBUG=@ENABLE_DEBUG@ "
+ 
+ 
diff --git a/icu.patches/icu-54.description b/icu.patches/icu-54.description
new file mode 100644
index 0000000..8471de5
--- /dev/null
+++ b/icu.patches/icu-54.description
@@ -0,0 +1 @@
+Disable parallelism due to build errors.
diff --git a/icu.patches/icu-54.patch b/icu.patches/icu-54.patch
new file mode 100644
index 0000000..e6b2e5c
--- /dev/null
+++ b/icu.patches/icu-54.patch
@@ -0,0 +1,12 @@
+diff -Naur a/source/extra/uconv/Makefile.in b/source/extra/uconv/Makefile.in
+--- a/source/extra/uconv/Makefile.in	2015-02-20 15:18:50.853811159 -0800
++++ b/source/extra/uconv/Makefile.in	2015-02-20 15:19:17.854094705 -0800
+@@ -7,6 +7,8 @@
+ ## Makefile.in for ICU - uconv
+ ## Steven  R. Loomis
+ 
++.NOTPARALLEL:
++
+ ## Set the following to dll or static or common..
+ UCONVMSG_MODE=static
+ ##############################################################
diff --git a/icu.patches/icu-55.description b/icu.patches/icu-55.description
new file mode 100644
index 0000000..1051573
--- /dev/null
+++ b/icu.patches/icu-55.description
@@ -0,0 +1,4 @@
+Delete unused portion of icu/source/data from the data shared library (libicudata.so).
+The idea on how to trim the fat from ICU was taken from the guidelines on their website
+located here:  
+http://userguide.icu-project.org/icudata#TOC-Reducing-the-Size-of-ICU-s-Data:-Conversion-Tables
diff --git a/icu.patches/icu-55.patch b/icu.patches/icu-55.patch
new file mode 100644
index 0000000..5d3dc02
--- /dev/null
+++ b/icu.patches/icu-55.patch
@@ -0,0 +1,943 @@
+diff -Naur a/source/data/brkitr/brkfiles.mk b/source/data/brkitr/brkfiles.mk
+--- a/source/data/brkitr/brkfiles.mk	2010-04-28 08:28:24.000000000 -0700
++++ b/source/data/brkitr/brkfiles.mk	1969-12-31 16:00:00.000000000 -0800
+@@ -1,47 +0,0 @@
+-# *   Copyright (C) 1998-2010, International Business Machines
+-# *   Corporation and others.  All Rights Reserved.
+-BRK_RES_CLDR_VERSION = 1.8.1
+-# A list of txt's to build
+-# Note:
+-#
+-#   If you are thinking of modifying this file, READ THIS.
+-#
+-# Instead of changing this file [unless you want to check it back in],
+-# you should consider creating a 'brklocal.mk' file in this same directory.
+-# Then, you can have your local changes remain even if you upgrade or
+-# reconfigure ICU.
+-#
+-# Example 'brklocal.mk' files:
+-#
+-#  * To add an additional locale to the list:
+-#    _____________________________________________________
+-#    |  BRK_RES_SOURCE_LOCAL =   myLocale.txt ...
+-#
+-#  * To REPLACE the default list and only build with a few
+-#    locales:
+-#    _____________________________________________________
+-#    |  BRK_RES_SOURCE = ar.txt ar_AE.txt en.txt de.txt zh.txt
+-#
+-#
+-# Generated by LDML2ICUConverter, from LDML source files.
+-
+-# Aliases without a corresponding xx.xml file (see icu-config.xml & build.xml)
+-BRK_RES_SYNTHETIC_ALIAS =
+-
+-
+-# All aliases (to not be included under 'installed'), but not including root.
+-BRK_RES_ALIAS_SOURCE = $(BRK_RES_SYNTHETIC_ALIAS)
+-
+-
+-# List of compact trie dictionary files (ctd).
+-BRK_CTD_SOURCE =  thaidict.txt 
+-
+-
+-# List of break iterator files (brk).
+-BRK_SOURCE =  sent_el.txt word_POSIX.txt word_ja.txt char.txt word.txt line.txt sent.txt title.txt char_th.txt
+-
+-
+-# Ordinary resources
+-BRK_RES_SOURCE = el.txt en.txt en_US.txt en_US_POSIX.txt\
+- ja.txt th.txt
+-
+diff -Naur a/source/data/coll/colfiles.mk b/source/data/coll/colfiles.mk
+--- a/source/data/coll/colfiles.mk	2010-04-28 08:28:20.000000000 -0700
++++ b/source/data/coll/colfiles.mk	1969-12-31 16:00:00.000000000 -0800
+@@ -1,96 +0,0 @@
+-# *   Copyright (C) 1998-2010, International Business Machines
+-# *   Corporation and others.  All Rights Reserved.
+-COLLATION_CLDR_VERSION = 1.8.1
+-# A list of txt's to build
+-# Note:
+-#
+-#   If you are thinking of modifying this file, READ THIS.
+-#
+-# Instead of changing this file [unless you want to check it back in],
+-# you should consider creating a 'collocal.mk' file in this same directory.
+-# Then, you can have your local changes remain even if you upgrade or
+-# reconfigure ICU.
+-#
+-# Example 'collocal.mk' files:
+-#
+-#  * To add an additional locale to the list:
+-#    _____________________________________________________
+-#    |  COLLATION_SOURCE_LOCAL =   myLocale.txt ...
+-#
+-#  * To REPLACE the default list and only build with a few
+-#    locales:
+-#    _____________________________________________________
+-#    |  COLLATION_SOURCE = ar.txt ar_AE.txt en.txt de.txt zh.txt
+-#
+-#
+-# Generated by LDML2ICUConverter, from LDML source files.
+-
+-# Aliases without a corresponding xx.xml file (see icu-config.xml & build.xml)
+-COLLATION_SYNTHETIC_ALIAS = de_.txt de__PHONEBOOK.txt es_.txt es__TRADITIONAL.txt\
+- hi_.txt hi__DIRECT.txt in.txt in_ID.txt iw.txt\
+- iw_IL.txt no.txt no_NO.txt pa_IN.txt sh.txt\
+- sh_BA.txt sh_YU.txt sr_BA.txt sr_ME.txt sr_RS.txt\
+- zh_.txt zh_CN.txt zh_HK.txt zh_MO.txt zh_SG.txt\
+- zh_TW.txt zh_TW_STROKE.txt zh__PINYIN.txt
+-
+-
+-# All aliases (to not be included under 'installed'), but not including root.
+-COLLATION_ALIAS_SOURCE = $(COLLATION_SYNTHETIC_ALIAS)
+-
+-
+-# Empty locales, used for validSubLocale fallback.
+-COLLATION_EMPTY_SOURCE = af_NA.txt af_ZA.txt ar_AE.txt ar_BH.txt\
+- ar_DZ.txt ar_EG.txt ar_IQ.txt ar_JO.txt ar_KW.txt\
+- ar_LB.txt ar_LY.txt ar_MA.txt ar_OM.txt ar_QA.txt\
+- ar_SA.txt ar_SD.txt ar_SY.txt ar_TN.txt ar_YE.txt\
+- as_IN.txt az_Latn.txt az_Latn_AZ.txt be_BY.txt bg_BG.txt\
+- bn_BD.txt bn_IN.txt ca_ES.txt cs_CZ.txt cy_GB.txt\
+- da_DK.txt de_AT.txt de_BE.txt de_CH.txt de_DE.txt\
+- de_LU.txt el_GR.txt en_AU.txt en_BW.txt en_CA.txt\
+- en_GB.txt en_HK.txt en_IE.txt en_IN.txt en_MT.txt\
+- en_NZ.txt en_PH.txt en_SG.txt en_US.txt en_US_POSIX.txt\
+- en_VI.txt en_ZA.txt en_ZW.txt es_AR.txt es_BO.txt\
+- es_CL.txt es_CO.txt es_CR.txt es_DO.txt es_EC.txt\
+- es_ES.txt es_GT.txt es_HN.txt es_MX.txt es_NI.txt\
+- es_PA.txt es_PE.txt es_PR.txt es_PY.txt es_SV.txt\
+- es_US.txt es_UY.txt es_VE.txt et_EE.txt fa_IR.txt\
+- fi_FI.txt fo_FO.txt fr_BE.txt fr_CA.txt fr_CH.txt\
+- fr_FR.txt fr_LU.txt ga.txt ga_IE.txt gu_IN.txt\
+- ha_Latn.txt ha_Latn_GH.txt ha_Latn_NE.txt ha_Latn_NG.txt he_IL.txt\
+- hi_IN.txt hr_HR.txt hu_HU.txt hy_AM.txt id.txt\
+- id_ID.txt ig_NG.txt is_IS.txt it_CH.txt it_IT.txt\
+- ja_JP.txt ka.txt ka_GE.txt kk_KZ.txt kl_GL.txt\
+- kn_IN.txt ko_KR.txt kok_IN.txt lt_LT.txt lv_LV.txt\
+- mk_MK.txt ml_IN.txt mr_IN.txt ms.txt ms_BN.txt\
+- ms_MY.txt mt_MT.txt nb_NO.txt nl.txt nl_BE.txt\
+- nl_NL.txt nn_NO.txt om_ET.txt om_KE.txt or_IN.txt\
+- pa_Arab.txt pa_Arab_PK.txt pa_Guru.txt pa_Guru_IN.txt pl_PL.txt\
+- ps_AF.txt pt.txt pt_BR.txt pt_PT.txt ro_RO.txt\
+- ru_RU.txt ru_UA.txt si_LK.txt sk_SK.txt sl_SI.txt\
+- sq_AL.txt sr_Cyrl.txt sr_Cyrl_BA.txt sr_Cyrl_ME.txt sr_Cyrl_RS.txt\
+- sr_Latn_BA.txt sr_Latn_ME.txt sr_Latn_RS.txt st.txt st_LS.txt\
+- st_ZA.txt sv_FI.txt sv_SE.txt sw_KE.txt sw_TZ.txt\
+- ta_IN.txt te_IN.txt th_TH.txt tr_TR.txt uk_UA.txt\
+- ur_IN.txt ur_PK.txt vi_VN.txt xh.txt xh_ZA.txt\
+- yo_NG.txt zh_Hans.txt zh_Hans_CN.txt zh_Hans_SG.txt zh_Hant_HK.txt\
+- zh_Hant_MO.txt zh_Hant_TW.txt zu.txt zu_ZA.txt
+-
+-
+-# Ordinary resources
+-COLLATION_SOURCE = $(COLLATION_EMPTY_SOURCE) af.txt ar.txt as.txt az.txt\
+- be.txt bg.txt bn.txt ca.txt cs.txt\
+- cy.txt da.txt de.txt el.txt en.txt\
+- en_BE.txt eo.txt es.txt et.txt fa.txt\
+- fa_AF.txt fi.txt fil.txt fo.txt fr.txt\
+- gu.txt ha.txt haw.txt he.txt hi.txt\
+- hr.txt hu.txt hy.txt ig.txt is.txt\
+- it.txt ja.txt kk.txt kl.txt km.txt\
+- kn.txt ko.txt kok.txt lt.txt lv.txt\
+- mk.txt ml.txt mr.txt mt.txt nb.txt\
+- nn.txt om.txt or.txt pa.txt pl.txt\
+- ps.txt ro.txt ru.txt si.txt sk.txt\
+- sl.txt sq.txt sr.txt sr_Latn.txt sv.txt\
+- sw.txt ta.txt te.txt th.txt to.txt\
+- tr.txt uk.txt ur.txt vi.txt yo.txt\
+- zh.txt zh_Hant.txt
+-
+diff -Naur a/source/data/curr/resfiles.mk b/source/data/curr/resfiles.mk
+--- a/source/data/curr/resfiles.mk	2010-04-28 08:28:36.000000000 -0700
++++ b/source/data/curr/resfiles.mk	1969-12-31 16:00:00.000000000 -0800
+@@ -1,87 +0,0 @@
+-# *   Copyright (C) 1998-2010, International Business Machines
+-# *   Corporation and others.  All Rights Reserved.
+-CURR_CLDR_VERSION = 1.8.1
+-# A list of txt's to build
+-# Note:
+-#
+-#   If you are thinking of modifying this file, READ THIS.
+-#
+-# Instead of changing this file [unless you want to check it back in],
+-# you should consider creating a 'reslocal.mk' file in this same directory.
+-# Then, you can have your local changes remain even if you upgrade or
+-# reconfigure ICU.
+-#
+-# Example 'reslocal.mk' files:
+-#
+-#  * To add an additional locale to the list:
+-#    _____________________________________________________
+-#    |  CURR_SOURCE_LOCAL =   myLocale.txt ...
+-#
+-#  * To REPLACE the default list and only build with a few
+-#    locales:
+-#    _____________________________________________________
+-#    |  CURR_SOURCE = ar.txt ar_AE.txt en.txt de.txt zh.txt
+-#
+-#
+-# Generated by LDML2ICUConverter, from LDML source files.
+-
+-# Aliases without a corresponding xx.xml file (see icu-config.xml & build.xml)
+-CURR_SYNTHETIC_ALIAS = en_RH.txt en_ZW.txt he_IL.txt id_ID.txt\
+- in_ID.txt iw_IL.txt ja_JP.txt ja_JP_TRADITIONAL.txt nb_NO.txt\
+- nn_NO.txt no_NO.txt no_NO_NY.txt th_TH.txt th_TH_TRADITIONAL.txt
+-
+-
+-# All aliases (to not be included under 'installed'), but not including root.
+-CURR_ALIAS_SOURCE = $(CURR_SYNTHETIC_ALIAS) az_AZ.txt ha_GH.txt ha_NE.txt ha_NG.txt\
+- in.txt iw.txt kk_KZ.txt no.txt pa_IN.txt\
+- pa_PK.txt sh.txt sh_BA.txt sh_CS.txt sh_YU.txt\
+- shi_MA.txt sr_BA.txt sr_CS.txt sr_Cyrl_CS.txt sr_Cyrl_YU.txt\
+- sr_Latn_CS.txt sr_Latn_YU.txt sr_ME.txt sr_RS.txt sr_YU.txt\
+- tl.txt tzm_MA.txt uz_AF.txt uz_UZ.txt zh_CN.txt\
+- zh_HK.txt zh_MO.txt zh_SG.txt zh_TW.txt
+-
+-
+-# Ordinary resources
+-CURR_SOURCE = af.txt ak.txt am.txt ar.txt\
+- as.txt asa.txt az.txt az_Cyrl.txt az_Latn.txt\
+- az_Latn_AZ.txt be.txt bem.txt bez.txt bg.txt\
+- bm.txt bn.txt bo.txt ca.txt cgg.txt\
+- chr.txt cs.txt cy.txt da.txt dav.txt\
+- de.txt de_BE.txt de_LU.txt ebu.txt ee.txt\
+- el.txt en.txt en_AU.txt en_BE.txt en_BW.txt\
+- en_BZ.txt en_CA.txt en_HK.txt en_JM.txt en_MT.txt\
+- en_NA.txt en_NZ.txt en_PH.txt en_PK.txt en_SG.txt\
+- en_TT.txt eo.txt es.txt es_AR.txt es_CL.txt\
+- es_CO.txt es_EC.txt es_GT.txt es_HN.txt es_MX.txt\
+- es_PR.txt es_US.txt es_UY.txt et.txt eu.txt\
+- fa.txt fa_AF.txt ff.txt fi.txt fil.txt\
+- fo.txt fr.txt fr_CA.txt fr_LU.txt ga.txt\
+- gl.txt gsw.txt gu.txt guz.txt gv.txt\
+- ha.txt ha_Latn.txt ha_Latn_GH.txt ha_Latn_NE.txt ha_Latn_NG.txt\
+- haw.txt he.txt hi.txt hr.txt hu.txt\
+- hy.txt id.txt ig.txt ii.txt is.txt\
+- it.txt ja.txt jmc.txt ka.txt kab.txt\
+- kam.txt kde.txt kea.txt khq.txt ki.txt\
+- kk.txt kk_Cyrl.txt kk_Cyrl_KZ.txt kl.txt kln.txt\
+- km.txt kn.txt ko.txt kok.txt kw.txt\
+- lag.txt lg.txt lt.txt luo.txt luy.txt\
+- lv.txt mas.txt mer.txt mfe.txt mg.txt\
+- mk.txt ml.txt mr.txt ms.txt ms_BN.txt\
+- mt.txt naq.txt nb.txt nd.txt ne.txt\
+- ne_IN.txt nl.txt nn.txt nyn.txt om.txt\
+- or.txt pa.txt pa_Arab.txt pa_Arab_PK.txt pa_Guru.txt\
+- pa_Guru_IN.txt pl.txt ps.txt pt.txt pt_PT.txt\
+- rm.txt ro.txt rof.txt ru.txt rw.txt\
+- rwk.txt saq.txt seh.txt ses.txt sg.txt\
+- shi.txt shi_Latn.txt shi_Latn_MA.txt shi_Tfng.txt si.txt\
+- sk.txt sl.txt sn.txt so.txt sq.txt\
+- sr.txt sr_Cyrl.txt sr_Cyrl_BA.txt sr_Cyrl_RS.txt sr_Latn.txt\
+- sr_Latn_BA.txt sr_Latn_ME.txt sr_Latn_RS.txt sv.txt sw.txt\
+- ta.txt te.txt teo.txt th.txt ti.txt\
+- to.txt tr.txt tzm.txt tzm_Latn.txt tzm_Latn_MA.txt\
+- uk.txt ur.txt uz.txt uz_Arab.txt uz_Arab_AF.txt\
+- uz_Cyrl.txt uz_Cyrl_UZ.txt uz_Latn.txt vi.txt vun.txt\
+- xog.txt yo.txt zh.txt zh_Hans.txt zh_Hans_CN.txt\
+- zh_Hans_HK.txt zh_Hans_SG.txt zh_Hant.txt zh_Hant_HK.txt zh_Hant_MO.txt\
+- zh_Hant_TW.txt zu.txt
+-
+diff -Naur a/source/data/lang/resfiles.mk b/source/data/lang/resfiles.mk
+--- a/source/data/lang/resfiles.mk	2010-04-28 08:27:56.000000000 -0700
++++ b/source/data/lang/resfiles.mk	2015-07-22 16:59:03.907938679 -0700
+@@ -26,57 +26,17 @@
+ # Generated by LDML2ICUConverter, from LDML source files.
+ 
+ # Aliases without a corresponding xx.xml file (see icu-config.xml & build.xml)
+-LANG_SYNTHETIC_ALIAS = en_RH.txt en_ZW.txt he_IL.txt id_ID.txt\
+- in_ID.txt iw_IL.txt ja_JP.txt ja_JP_TRADITIONAL.txt nb_NO.txt\
+- nn_NO.txt no_NO.txt no_NO_NY.txt th_TH.txt th_TH_TRADITIONAL.txt
++LANG_SYNTHETIC_ALIAS =
+ 
+ 
+ # All aliases (to not be included under 'installed'), but not including root.
+-LANG_ALIAS_SOURCE = $(LANG_SYNTHETIC_ALIAS) az_AZ.txt ha_GH.txt ha_NE.txt ha_NG.txt\
+- in.txt iw.txt kk_KZ.txt no.txt pa_IN.txt\
+- pa_PK.txt sh.txt sh_BA.txt sh_CS.txt sh_YU.txt\
+- shi_MA.txt sr_BA.txt sr_CS.txt sr_Cyrl_CS.txt sr_Cyrl_YU.txt\
+- sr_Latn_CS.txt sr_Latn_YU.txt sr_ME.txt sr_RS.txt sr_YU.txt\
+- tl.txt tzm_MA.txt uz_AF.txt uz_UZ.txt zh_CN.txt\
+- zh_HK.txt zh_MO.txt zh_SG.txt zh_TW.txt
++LANG_ALIAS_SOURCE = $(LANG_SYNTHETIC_ALIAS)
+ 
+ 
+ # Ordinary resources
+-LANG_SOURCE = af.txt ak.txt am.txt ar.txt\
+- as.txt asa.txt az.txt az_Cyrl.txt az_Latn.txt\
+- az_Latn_AZ.txt be.txt bem.txt bez.txt bg.txt\
+- bm.txt bn.txt bn_IN.txt bo.txt ca.txt\
+- cgg.txt chr.txt cs.txt cy.txt da.txt\
+- dav.txt de.txt de_CH.txt ebu.txt ee.txt\
+- el.txt en.txt eo.txt es.txt es_AR.txt\
+- es_CL.txt et.txt eu.txt fa.txt fa_AF.txt\
+- ff.txt fi.txt fil.txt fo.txt fr.txt\
+- ga.txt gl.txt gsw.txt gu.txt guz.txt\
+- gv.txt ha.txt ha_Latn.txt ha_Latn_GH.txt ha_Latn_NE.txt\
+- ha_Latn_NG.txt haw.txt he.txt hi.txt hr.txt\
+- hu.txt hy.txt id.txt ig.txt ii.txt\
+- is.txt it.txt ja.txt jmc.txt ka.txt\
+- kab.txt kam.txt kde.txt kea.txt khq.txt\
+- ki.txt kk.txt kk_Cyrl.txt kk_Cyrl_KZ.txt kl.txt\
+- kln.txt km.txt kn.txt ko.txt kok.txt\
+- kw.txt lag.txt lg.txt lt.txt luo.txt\
+- luy.txt lv.txt mas.txt mer.txt mfe.txt\
+- mg.txt mk.txt ml.txt mr.txt ms.txt\
+- mt.txt naq.txt nb.txt nd.txt ne.txt\
+- nl.txt nl_BE.txt nn.txt nyn.txt om.txt\
+- or.txt pa.txt pa_Arab.txt pa_Arab_PK.txt pa_Guru.txt\
+- pa_Guru_IN.txt pl.txt ps.txt pt.txt pt_PT.txt\
+- rm.txt ro.txt rof.txt ru.txt ru_UA.txt\
+- rw.txt rwk.txt saq.txt seh.txt ses.txt\
+- sg.txt shi.txt shi_Latn.txt shi_Latn_MA.txt shi_Tfng.txt\
+- si.txt sk.txt sl.txt sn.txt so.txt\
+- sq.txt sr.txt sr_Cyrl.txt sr_Cyrl_BA.txt sr_Cyrl_RS.txt\
+- sr_Latn.txt sr_Latn_BA.txt sr_Latn_ME.txt sr_Latn_RS.txt sv.txt\
+- sv_FI.txt sw.txt ta.txt te.txt teo.txt\
+- th.txt ti.txt to.txt tr.txt tzm.txt\
+- tzm_Latn.txt tzm_Latn_MA.txt uk.txt ur.txt uz.txt\
+- uz_Arab.txt uz_Arab_AF.txt uz_Cyrl.txt uz_Cyrl_UZ.txt uz_Latn.txt\
+- vi.txt vun.txt xog.txt yo.txt zh.txt\
+- zh_Hans.txt zh_Hans_CN.txt zh_Hans_SG.txt zh_Hant.txt zh_Hant_HK.txt\
+- zh_Hant_MO.txt zh_Hant_TW.txt zu.txt
++LANG_SOURCE = de.txt\
++ en.txt\
++ es.txt\
++ fr.txt\
++ nl.txt
+ 
+diff -Naur a/source/data/locales/resfiles.mk b/source/data/locales/resfiles.mk
+--- a/source/data/locales/resfiles.mk	2010-04-28 08:28:08.000000000 -0700
++++ b/source/data/locales/resfiles.mk	1969-12-31 16:00:00.000000000 -0800
+@@ -1,127 +0,0 @@
+-# *   Copyright (C) 1998-2010, International Business Machines
+-# *   Corporation and others.  All Rights Reserved.
+-GENRB_CLDR_VERSION = 1.8.1
+-# A list of txt's to build
+-# Note:
+-#
+-#   If you are thinking of modifying this file, READ THIS.
+-#
+-# Instead of changing this file [unless you want to check it back in],
+-# you should consider creating a 'reslocal.mk' file in this same directory.
+-# Then, you can have your local changes remain even if you upgrade or
+-# reconfigure ICU.
+-#
+-# Example 'reslocal.mk' files:
+-#
+-#  * To add an additional locale to the list:
+-#    _____________________________________________________
+-#    |  GENRB_SOURCE_LOCAL =   myLocale.txt ...
+-#
+-#  * To REPLACE the default list and only build with a few
+-#    locales:
+-#    _____________________________________________________
+-#    |  GENRB_SOURCE = ar.txt ar_AE.txt en.txt de.txt zh.txt
+-#
+-#
+-# Generated by LDML2ICUConverter, from LDML source files.
+-
+-# Aliases without a corresponding xx.xml file (see icu-config.xml & build.xml)
+-GENRB_SYNTHETIC_ALIAS = en_RH.txt in_ID.txt iw_IL.txt ja_JP_TRADITIONAL.txt\
+- no_NO.txt no_NO_NY.txt th_TH_TRADITIONAL.txt
+-
+-
+-# All aliases (to not be included under 'installed'), but not including root.
+-GENRB_ALIAS_SOURCE = $(GENRB_SYNTHETIC_ALIAS) az_AZ.txt ha_GH.txt ha_NE.txt ha_NG.txt\
+- in.txt iw.txt kk_KZ.txt no.txt pa_IN.txt\
+- pa_PK.txt sh.txt sh_BA.txt sh_CS.txt sh_YU.txt\
+- shi_MA.txt sr_BA.txt sr_CS.txt sr_Cyrl_CS.txt sr_Cyrl_YU.txt\
+- sr_Latn_CS.txt sr_Latn_YU.txt sr_ME.txt sr_RS.txt sr_YU.txt\
+- tl.txt tzm_MA.txt uz_AF.txt uz_UZ.txt zh_CN.txt\
+- zh_HK.txt zh_MO.txt zh_SG.txt zh_TW.txt
+-
+-
+-# Ordinary resources
+-GENRB_SOURCE = af.txt af_NA.txt af_ZA.txt ak.txt\
+- ak_GH.txt am.txt am_ET.txt ar.txt ar_AE.txt\
+- ar_BH.txt ar_DZ.txt ar_EG.txt ar_IQ.txt ar_JO.txt\
+- ar_KW.txt ar_LB.txt ar_LY.txt ar_MA.txt ar_OM.txt\
+- ar_QA.txt ar_SA.txt ar_SD.txt ar_SY.txt ar_TN.txt\
+- ar_YE.txt as.txt as_IN.txt asa.txt asa_TZ.txt\
+- az.txt az_Cyrl.txt az_Cyrl_AZ.txt az_Latn.txt az_Latn_AZ.txt\
+- be.txt be_BY.txt bem.txt bem_ZM.txt bez.txt\
+- bez_TZ.txt bg.txt bg_BG.txt bm.txt bm_ML.txt\
+- bn.txt bn_BD.txt bn_IN.txt bo.txt bo_CN.txt\
+- bo_IN.txt ca.txt ca_ES.txt cgg.txt cgg_UG.txt\
+- chr.txt chr_US.txt cs.txt cs_CZ.txt cy.txt\
+- cy_GB.txt da.txt da_DK.txt dav.txt dav_KE.txt\
+- de.txt de_AT.txt de_BE.txt de_CH.txt de_DE.txt\
+- de_LI.txt de_LU.txt ebu.txt ebu_KE.txt ee.txt\
+- ee_GH.txt ee_TG.txt el.txt el_CY.txt el_GR.txt\
+- en.txt en_AU.txt en_BE.txt en_BW.txt en_BZ.txt\
+- en_CA.txt en_GB.txt en_HK.txt en_IE.txt en_IN.txt\
+- en_JM.txt en_MH.txt en_MT.txt en_MU.txt en_NA.txt\
+- en_NZ.txt en_PH.txt en_PK.txt en_SG.txt en_TT.txt\
+- en_US.txt en_US_POSIX.txt en_VI.txt en_ZA.txt en_ZW.txt\
+- eo.txt es.txt es_AR.txt es_BO.txt es_CL.txt\
+- es_CO.txt es_CR.txt es_DO.txt es_EC.txt es_ES.txt\
+- es_GQ.txt es_GT.txt es_HN.txt es_MX.txt es_NI.txt\
+- es_PA.txt es_PE.txt es_PR.txt es_PY.txt es_SV.txt\
+- es_US.txt es_UY.txt es_VE.txt et.txt et_EE.txt\
+- eu.txt eu_ES.txt fa.txt fa_AF.txt fa_IR.txt\
+- ff.txt ff_SN.txt fi.txt fi_FI.txt fil.txt\
+- fil_PH.txt fo.txt fo_FO.txt fr.txt fr_BE.txt\
+- fr_BL.txt fr_CA.txt fr_CF.txt fr_CH.txt fr_CI.txt\
+- fr_CM.txt fr_FR.txt fr_GN.txt fr_GP.txt fr_LU.txt\
+- fr_MC.txt fr_MF.txt fr_MG.txt fr_ML.txt fr_MQ.txt\
+- fr_NE.txt fr_RE.txt fr_SN.txt ga.txt ga_IE.txt\
+- gl.txt gl_ES.txt gsw.txt gsw_CH.txt gu.txt\
+- gu_IN.txt guz.txt guz_KE.txt gv.txt gv_GB.txt\
+- ha.txt ha_Latn.txt ha_Latn_GH.txt ha_Latn_NE.txt ha_Latn_NG.txt\
+- haw.txt haw_US.txt he.txt he_IL.txt hi.txt\
+- hi_IN.txt hr.txt hr_HR.txt hu.txt hu_HU.txt\
+- hy.txt hy_AM.txt id.txt id_ID.txt ig.txt\
+- ig_NG.txt ii.txt ii_CN.txt is.txt is_IS.txt\
+- it.txt it_CH.txt it_IT.txt ja.txt ja_JP.txt\
+- jmc.txt jmc_TZ.txt ka.txt ka_GE.txt kab.txt\
+- kab_DZ.txt kam.txt kam_KE.txt kde.txt kde_TZ.txt\
+- kea.txt kea_CV.txt khq.txt khq_ML.txt ki.txt\
+- ki_KE.txt kk.txt kk_Cyrl.txt kk_Cyrl_KZ.txt kl.txt\
+- kl_GL.txt kln.txt kln_KE.txt km.txt km_KH.txt\
+- kn.txt kn_IN.txt ko.txt ko_KR.txt kok.txt\
+- kok_IN.txt kw.txt kw_GB.txt lag.txt lag_TZ.txt\
+- lg.txt lg_UG.txt lt.txt lt_LT.txt luo.txt\
+- luo_KE.txt luy.txt luy_KE.txt lv.txt lv_LV.txt\
+- mas.txt mas_KE.txt mas_TZ.txt mer.txt mer_KE.txt\
+- mfe.txt mfe_MU.txt mg.txt mg_MG.txt mk.txt\
+- mk_MK.txt ml.txt ml_IN.txt mr.txt mr_IN.txt\
+- ms.txt ms_BN.txt ms_MY.txt mt.txt mt_MT.txt\
+- naq.txt naq_NA.txt nb.txt nb_NO.txt nd.txt\
+- nd_ZW.txt ne.txt ne_IN.txt ne_NP.txt nl.txt\
+- nl_BE.txt nl_NL.txt nn.txt nn_NO.txt nyn.txt\
+- nyn_UG.txt om.txt om_ET.txt om_KE.txt or.txt\
+- or_IN.txt pa.txt pa_Arab.txt pa_Arab_PK.txt pa_Guru.txt\
+- pa_Guru_IN.txt pl.txt pl_PL.txt ps.txt ps_AF.txt\
+- pt.txt pt_BR.txt pt_GW.txt pt_MZ.txt pt_PT.txt\
+- rm.txt rm_CH.txt ro.txt ro_MD.txt ro_RO.txt\
+- rof.txt rof_TZ.txt ru.txt ru_MD.txt ru_RU.txt\
+- ru_UA.txt rw.txt rw_RW.txt rwk.txt rwk_TZ.txt\
+- saq.txt saq_KE.txt seh.txt seh_MZ.txt ses.txt\
+- ses_ML.txt sg.txt sg_CF.txt shi.txt shi_Latn.txt\
+- shi_Latn_MA.txt shi_Tfng.txt shi_Tfng_MA.txt si.txt si_LK.txt\
+- sk.txt sk_SK.txt sl.txt sl_SI.txt sn.txt\
+- sn_ZW.txt so.txt so_DJ.txt so_ET.txt so_KE.txt\
+- so_SO.txt sq.txt sq_AL.txt sr.txt sr_Cyrl.txt\
+- sr_Cyrl_BA.txt sr_Cyrl_ME.txt sr_Cyrl_RS.txt sr_Latn.txt sr_Latn_BA.txt\
+- sr_Latn_ME.txt sr_Latn_RS.txt sv.txt sv_FI.txt sv_SE.txt\
+- sw.txt sw_KE.txt sw_TZ.txt ta.txt ta_IN.txt\
+- ta_LK.txt te.txt te_IN.txt teo.txt teo_KE.txt\
+- teo_UG.txt th.txt th_TH.txt ti.txt ti_ER.txt\
+- ti_ET.txt to.txt to_TO.txt tr.txt tr_TR.txt\
+- tzm.txt tzm_Latn.txt tzm_Latn_MA.txt uk.txt uk_UA.txt\
+- ur.txt ur_IN.txt ur_PK.txt uz.txt uz_Arab.txt\
+- uz_Arab_AF.txt uz_Cyrl.txt uz_Cyrl_UZ.txt uz_Latn.txt uz_Latn_UZ.txt\
+- vi.txt vi_VN.txt vun.txt vun_TZ.txt xog.txt\
+- xog_UG.txt yo.txt yo_NG.txt zh.txt zh_Hans.txt\
+- zh_Hans_CN.txt zh_Hans_HK.txt zh_Hans_MO.txt zh_Hans_SG.txt zh_Hant.txt\
+- zh_Hant_HK.txt zh_Hant_MO.txt zh_Hant_TW.txt zu.txt zu_ZA.txt
+-
+diff -Naur a/source/data/mappings/ucmcore.mk b/source/data/mappings/ucmcore.mk
+--- a/source/data/mappings/ucmcore.mk	2010-04-28 08:28:48.000000000 -0700
++++ b/source/data/mappings/ucmcore.mk	1969-12-31 16:00:00.000000000 -0800
+@@ -1,28 +0,0 @@
+-# Copyright (c) 1999-2007, International Business Machines Corporation and
+-# others. All Rights Reserved.
+-# A list of UCM's to build for core MIME/Unix/Windows encodings
+-
+-# Note: A number of encodings are handled with purely algorithmic converters,
+-# without any mapping tables:
+-# US-ASCII, ISO 8859-1, UTF-7/8/16/32, SCSU
+-
+-# Listed here:
+-
+-# ISO 8859-2..9, 15
+-# Windows-125x
+-# EUC-CN, GBK (Windows cp936), GB 18030
+-# Big5 (Windows cp950)
+-# SJIS (Windows cp932), EUC-JP
+-# EUC-KR, KS C 5601, Windows cp949
+-
+-UCM_SOURCE_CORE=ibm-912_P100-1995.ucm ibm-913_P100-2000.ucm\
+-ibm-914_P100-1995.ucm ibm-915_P100-1995.ucm ibm-5012_P100-1999.ucm\
+-ibm-920_P100-1995.ucm ibm-923_P100-1998.ucm ibm-1089_P100-1995.ucm\
+-ibm-4909_P100-1999.ucm\
+-ibm-5346_P100-1998.ucm ibm-5347_P100-1998.ucm ibm-5348_P100-1997.ucm\
+-ibm-5349_P100-1998.ucm ibm-5350_P100-1998.ucm ibm-9447_P100-2002.ucm\
+-ibm-5352_P100-1998.ucm ibm-9449_P100-2002.ucm ibm-5354_P100-1998.ucm\
+-ibm-1383_P110-1999.ucm ibm-1386_P100-2001.ucm gb18030.ucm\
+-ibm-1373_P100-2002.ucm\
+-ibm-943_P15A-2003.ucm ibm-33722_P12A_P12A-2004_U2.ucm\
+-ibm-970_P110_P110-2006_U2.ucm ibm-949_P11A-1999.ucm ibm-1363_P11B-1998.ucm
+diff -Naur a/source/data/mappings/ucmebcdic.mk b/source/data/mappings/ucmebcdic.mk
+--- a/source/data/mappings/ucmebcdic.mk	2010-04-28 08:28:46.000000000 -0700
++++ b/source/data/mappings/ucmebcdic.mk	1969-12-31 16:00:00.000000000 -0800
+@@ -1,29 +0,0 @@
+-# Copyright (c) 1999-2010, International Business Machines Corporation and
+-# others. All Rights Reserved.
+-# A list of EBCDIC UCM's to build
+-# ibm-37 and ibm-1047 are already mentioned in makedata.mak and Makefile.in
+-
+-UCM_SOURCE_EBCDIC = ebcdic-xml-us.ucm\
+-ibm-1025_P100-1995.ucm ibm-1026_P100-1995.ucm ibm-1097_P100-1995.ucm\
+-ibm-1112_P100-1995.ucm ibm-1122_P100-1999.ucm ibm-1130_P100-1997.ucm\
+-ibm-1132_P100-1998.ucm ibm-1137_P100-1999.ucm ibm-1364_P110-2007.ucm\
+-ibm-1371_P100-1999.ucm ibm-1388_P103-2001.ucm ibm-1390_P110-2003.ucm\
+-ibm-1399_P110-2003.ucm ibm-870_P100-1995.ucm ibm-875_P100-1995.ucm\
+-ibm-838_P100-1995.ucm ibm-918_P100-1995.ucm ibm-930_P120-1999.ucm\
+-ibm-933_P110-1995.ucm ibm-935_P110-1999.ucm ibm-937_P110-1999.ucm\
+-ibm-939_P120-1999.ucm ibm-1123_P100-1995.ucm ibm-1140_P100-1997.ucm\
+-ibm-1141_P100-1997.ucm ibm-1142_P100-1997.ucm ibm-1143_P100-1997.ucm\
+-ibm-1144_P100-1997.ucm ibm-1145_P100-1997.ucm ibm-1146_P100-1997.ucm\
+-ibm-1147_P100-1997.ucm ibm-1148_P100-1997.ucm ibm-1149_P100-1997.ucm\
+-ibm-1153_P100-1999.ucm ibm-1154_P100-1999.ucm ibm-1155_P100-1999.ucm\
+-ibm-1156_P100-1999.ucm ibm-1157_P100-1999.ucm ibm-1158_P100-1999.ucm\
+-ibm-1160_P100-1999.ucm ibm-1164_P100-1999.ucm ibm-871_P100-1995.ucm\
+-ibm-12712_P100-1998.ucm ibm-16804_X110-1999.ucm ibm-273_P100-1995.ucm\
+-ibm-277_P100-1995.ucm ibm-278_P100-1995.ucm ibm-280_P100-1995.ucm\
+-ibm-284_P100-1995.ucm ibm-285_P100-1995.ucm ibm-290_P100-1995.ucm\
+-ibm-297_P100-1995.ucm ibm-420_X120-1999.ucm ibm-424_P100-1995.ucm\
+-ibm-4517_P100-2005.ucm ibm-4899_P100-1998.ucm ibm-4971_P100-1999.ucm\
+-ibm-500_P100-1995.ucm ibm-5123_P100-1999.ucm ibm-803_P100-1999.ucm\
+-ibm-8482_P100-1999.ucm ibm-9067_X100-2005.ucm ibm-16684_P110-2003.ucm
+-
+-#UCM_SOURCE_EBCDIC_IGNORE_SISO =
+\ No newline at end of file
+diff -Naur a/source/data/mappings/ucmfiles.mk b/source/data/mappings/ucmfiles.mk
+--- a/source/data/mappings/ucmfiles.mk	2010-04-28 08:28:46.000000000 -0700
++++ b/source/data/mappings/ucmfiles.mk	1969-12-31 16:00:00.000000000 -0800
+@@ -1,116 +0,0 @@
+-# Copyright (c) 1999-2010, International Business Machines Corporation and
+-# others. All Rights Reserved.
+-# A list of UCM's to build
+-# Note: 
+-#
+-#   If you are thinking of modifying this file, READ THIS. 
+-#
+-# Instead of changing this file [unless you want to check it back in],
+-# you should consider creating a 'ucmlocal.mk' file in this same directory.
+-# Then, you can have your local changes remain even if you upgrade or re
+-# configure the ICU.
+-#
+-# Example 'ucmlocal.mk' files:
+-#
+-#  * To add an additional converter to the list: 
+-#    _____________________________________________________
+-#    |  UCM_SOURCE_LOCAL =  myconverter.ucm ...
+-#
+-#  * To add EBCDIC converters that uses different SI/SO characters:
+-#    Note: ICU is updated to handle three EBCDIC converters (JIPS, KEIS, and JEF) which uses 
+-#          different SI/SO characters than the "standard" ones:  0xf/0xe.
+-#          This behaviour is done in the mbcs converter code and is turned on if for that converter
+-#          if the name contains either JIPS, KEIS, or JEF. (e.g. my_KEIS_converter.ucm) 
+-#    _____________________________________________________
+-#    |  UCM_SOURCE_EBCDIC_IGNORE_SISO_LOCAL = my_KEIS_converter.ucm
+-#
+-#  * To REPLACE the default list and only build with a few
+-#     converters:
+-#    _____________________________________________________
+-#    |  UCM_SOURCE = ibm-913.ucm ibm-949.ucm ibm-37.ucm
+-#
+-# If you are planning to exclude EBCDIC mappings in you data then please delete
+-# ucmebcdic.mk from the <icu>/source/data directory
+-#
+-
+-UCM_SOURCE_FILES = ibm-437_P100-1995.ucm\
+-ibm-737_P100-1997.ucm\
+-ibm-720_P100-1997.ucm\
+-ibm-775_P100-1996.ucm\
+-ibm-813_P100-1995.ucm\
+-ibm-850_P100-1995.ucm\
+-ibm-851_P100-1995.ucm\
+-ibm-852_P100-1995.ucm\
+-ibm-855_P100-1995.ucm\
+-ibm-856_P100-1995.ucm\
+-ibm-857_P100-1995.ucm\
+-ibm-858_P100-1997.ucm\
+-ibm-860_P100-1995.ucm\
+-ibm-861_P100-1995.ucm\
+-ibm-862_P100-1995.ucm\
+-ibm-863_P100-1995.ucm\
+-ibm-864_X110-1999.ucm\
+-ibm-865_P100-1995.ucm\
+-ibm-866_P100-1995.ucm\
+-ibm-867_P100-1998.ucm\
+-ibm-868_P100-1995.ucm\
+-ibm-869_P100-1995.ucm\
+-ibm-874_P100-1995.ucm\
+-ibm-878_P100-1996.ucm\
+-ibm-901_P100-1999.ucm\
+-ibm-902_P100-1999.ucm\
+-ibm-916_P100-1995.ucm\
+-ibm-921_P100-1995.ucm\
+-ibm-922_P100-1999.ucm\
+-ibm-1006_P100-1995.ucm\
+-ibm-1051_P100-1995.ucm\
+-ibm-1098_P100-1995.ucm\
+-ibm-1124_P100-1996.ucm\
+-ibm-1125_P100-1997.ucm\
+-ibm-1129_P100-1997.ucm\
+-ibm-1131_P100-1997.ucm\
+-ibm-1133_P100-1997.ucm\
+-ibm-1162_P100-1999.ucm\
+-ibm-1168_P100-2002.ucm\
+-ibm-1250_P100-1995.ucm\
+-ibm-1251_P100-1995.ucm\
+-ibm-1252_P100-2000.ucm\
+-ibm-1253_P100-1995.ucm\
+-ibm-1254_P100-1995.ucm\
+-ibm-1255_P100-1995.ucm\
+-ibm-1256_P110-1997.ucm\
+-ibm-1257_P100-1995.ucm\
+-ibm-1258_P100-1997.ucm\
+-ibm-1276_P100-1995.ucm\
+-ibm-5351_P100-1998.ucm\
+-ibm-5353_P100-1998.ucm\
+-ibm-942_P12A-1999.ucm\
+-ibm-943_P130-1999.ucm\
+-ibm-949_P110-1999.ucm\
+-ibm-950_P110-1999.ucm\
+-ibm-954_P101-2007.ucm\
+-ibm-964_P110-1999.ucm\
+-ibm-971_P100-1995.ucm\
+-ibm-1363_P110-1997.ucm\
+-ibm-1375_P100-2007.ucm\
+-ibm-5471_P100-2006.ucm\
+-ibm-9005_X110-2007.ucm\
+-ibm-9448_X100-2005.ucm\
+-ibm-33722_P120-1999.ucm\
+-iso-8859_10-1998.ucm\
+-iso-8859_11-2001.ucm\
+-iso-8859_14-1998.ucm\
+-macos-0_2-10.2.ucm\
+-macos-6_2-10.4.ucm\
+-macos-7_3-10.2.ucm\
+-macos-29-10.2.ucm\
+-macos-35-10.2.ucm\
+-windows-874-2000.ucm\
+-windows-936-2000.ucm\
+-windows-949-2000.ucm\
+-windows-950-2000.ucm\
+-jisx-212.ucm\
+-iso-ir-165.ucm cns-11643-1992.ucm\
+-ibm-5478_P100-1995.ucm\
+-icu-internal-25546.ucm lmb-excp.ucm
+-
+diff -Naur a/source/data/misc/miscfiles.mk b/source/data/misc/miscfiles.mk
+--- a/source/data/misc/miscfiles.mk	2010-04-28 08:28:24.000000000 -0700
++++ b/source/data/misc/miscfiles.mk	1969-12-31 16:00:00.000000000 -0800
+@@ -1,26 +0,0 @@
+-# *   Copyright (C) 2003-2010, International Business Machines
+-# *   Corporation and others.  All Rights Reserved.
+-# A list of txt's to build
+-# Note: 
+-#
+-#   If you are thinking of modifying this file, READ THIS. 
+-#
+-# Instead of changing this file [unless you want to check it back in],
+-# you should consider creating a 'misclocal.mk' file in this same directory.
+-# Then, you can have your local changes remain even if you upgrade or re-
+-# configure ICU.
+-#
+-# Example 'misclocal.mk' files:
+-#
+-#  * To add an additional file to the list: 
+-#    _____________________________________________________
+-#    |  MISC_SOURCE_LOCAL =   myFile.txt ...
+-#
+-#  * To REPLACE the default list and only build a subset of files:
+-#    _____________________________________________________
+-#    |  MISC_SOURCE = zoneinfo.txt
+-#
+-#
+-
+-MISC_SOURCE = \
+-zoneinfo64.txt supplementalData.txt likelySubtags.txt plurals.txt numberingSystems.txt icuver.txt icustd.txt metaZones.txt windowsZones.txt keyTypeData.txt timezoneTypes.txt
+diff -Naur a/source/data/rbnf/rbnffiles.mk b/source/data/rbnf/rbnffiles.mk
+--- a/source/data/rbnf/rbnffiles.mk	2010-04-28 08:28:16.000000000 -0700
++++ b/source/data/rbnf/rbnffiles.mk	1969-12-31 16:00:00.000000000 -0800
+@@ -1,50 +0,0 @@
+-# *   Copyright (C) 1998-2010, International Business Machines
+-# *   Corporation and others.  All Rights Reserved.
+-RBNF_CLDR_VERSION = 1.8.1
+-# A list of txt's to build
+-# Note:
+-#
+-#   If you are thinking of modifying this file, READ THIS.
+-#
+-# Instead of changing this file [unless you want to check it back in],
+-# you should consider creating a 'rbnflocal.mk' file in this same directory.
+-# Then, you can have your local changes remain even if you upgrade or
+-# reconfigure ICU.
+-#
+-# Example 'rbnflocal.mk' files:
+-#
+-#  * To add an additional locale to the list:
+-#    _____________________________________________________
+-#    |  RBNF_SOURCE_LOCAL =   myLocale.txt ...
+-#
+-#  * To REPLACE the default list and only build with a few
+-#    locales:
+-#    _____________________________________________________
+-#    |  RBNF_SOURCE = ar.txt ar_AE.txt en.txt de.txt zh.txt
+-#
+-#
+-# Generated by LDML2ICUConverter, from LDML source files.
+-
+-# Aliases without a corresponding xx.xml file (see icu-config.xml & build.xml)
+-RBNF_SYNTHETIC_ALIAS =
+-
+-
+-# All aliases (to not be included under 'installed'), but not including root.
+-RBNF_ALIAS_SOURCE = $(RBNF_SYNTHETIC_ALIAS)
+-
+-
+-# Ordinary resources
+-RBNF_SOURCE = af.txt am.txt ar.txt az.txt\
+- be.txt bg.txt ca.txt cs.txt cy.txt\
+- da.txt de.txt el.txt en.txt eo.txt\
+- es.txt et.txt fa.txt fa_AF.txt fi.txt\
+- fil.txt fo.txt fr.txt fr_BE.txt fr_CH.txt\
+- ga.txt he.txt hi.txt hr.txt hu.txt\
+- hy.txt id.txt is.txt it.txt ja.txt\
+- ka.txt kl.txt ko.txt lt.txt lv.txt\
+- mk.txt ms.txt mt.txt nb.txt nl.txt\
+- nn.txt pl.txt pt.txt pt_PT.txt ro.txt\
+- ru.txt sk.txt sl.txt sq.txt sr.txt\
+- sr_Latn.txt sv.txt ta.txt th.txt tr.txt\
+- uk.txt vi.txt zh.txt zh_Hant.txt
+-
+diff -Naur a/source/data/region/resfiles.mk b/source/data/region/resfiles.mk
+--- a/source/data/region/resfiles.mk	2010-04-28 08:28:12.000000000 -0700
++++ b/source/data/region/resfiles.mk	1969-12-31 16:00:00.000000000 -0800
+@@ -1,81 +0,0 @@
+-# *   Copyright (C) 1998-2010, International Business Machines
+-# *   Corporation and others.  All Rights Reserved.
+-REGION_CLDR_VERSION = 1.8.1
+-# A list of txt's to build
+-# Note:
+-#
+-#   If you are thinking of modifying this file, READ THIS.
+-#
+-# Instead of changing this file [unless you want to check it back in],
+-# you should consider creating a 'reslocal.mk' file in this same directory.
+-# Then, you can have your local changes remain even if you upgrade or
+-# reconfigure ICU.
+-#
+-# Example 'reslocal.mk' files:
+-#
+-#  * To add an additional locale to the list:
+-#    _____________________________________________________
+-#    |  REGION_SOURCE_LOCAL =   myLocale.txt ...
+-#
+-#  * To REPLACE the default list and only build with a few
+-#    locales:
+-#    _____________________________________________________
+-#    |  REGION_SOURCE = ar.txt ar_AE.txt en.txt de.txt zh.txt
+-#
+-#
+-# Generated by LDML2ICUConverter, from LDML source files.
+-
+-# Aliases without a corresponding xx.xml file (see icu-config.xml & build.xml)
+-REGION_SYNTHETIC_ALIAS = en_RH.txt en_ZW.txt he_IL.txt id_ID.txt\
+- in_ID.txt iw_IL.txt ja_JP.txt ja_JP_TRADITIONAL.txt nb_NO.txt\
+- nn_NO.txt no_NO.txt no_NO_NY.txt th_TH.txt th_TH_TRADITIONAL.txt
+-
+-
+-# All aliases (to not be included under 'installed'), but not including root.
+-REGION_ALIAS_SOURCE = $(REGION_SYNTHETIC_ALIAS) az_AZ.txt ha_GH.txt ha_NE.txt ha_NG.txt\
+- in.txt iw.txt kk_KZ.txt no.txt pa_IN.txt\
+- pa_PK.txt sh.txt sh_BA.txt sh_CS.txt sh_YU.txt\
+- shi_MA.txt sr_BA.txt sr_CS.txt sr_Cyrl_CS.txt sr_Cyrl_YU.txt\
+- sr_Latn_CS.txt sr_Latn_YU.txt sr_ME.txt sr_RS.txt sr_YU.txt\
+- tl.txt tzm_MA.txt uz_AF.txt uz_UZ.txt zh_CN.txt\
+- zh_HK.txt zh_MO.txt zh_SG.txt zh_TW.txt
+-
+-
+-# Ordinary resources
+-REGION_SOURCE = af.txt ak.txt am.txt ar.txt\
+- as.txt asa.txt az.txt az_Cyrl.txt az_Latn.txt\
+- az_Latn_AZ.txt be.txt bem.txt bez.txt bg.txt\
+- bm.txt bn.txt bo.txt ca.txt cgg.txt\
+- chr.txt cs.txt cy.txt da.txt dav.txt\
+- de.txt de_CH.txt ebu.txt ee.txt el.txt\
+- en.txt eo.txt es.txt es_CL.txt et.txt\
+- eu.txt fa.txt fa_AF.txt ff.txt fi.txt\
+- fil.txt fo.txt fr.txt ga.txt gl.txt\
+- gsw.txt gu.txt guz.txt gv.txt ha.txt\
+- ha_Latn.txt ha_Latn_GH.txt ha_Latn_NE.txt ha_Latn_NG.txt haw.txt\
+- he.txt hi.txt hr.txt hu.txt hy.txt\
+- id.txt ig.txt ii.txt is.txt it.txt\
+- ja.txt jmc.txt ka.txt kab.txt kam.txt\
+- kde.txt kea.txt khq.txt ki.txt kk.txt\
+- kk_Cyrl.txt kk_Cyrl_KZ.txt kl.txt kln.txt km.txt\
+- kn.txt ko.txt kok.txt kw.txt lag.txt\
+- lg.txt lt.txt luo.txt luy.txt lv.txt\
+- mas.txt mer.txt mfe.txt mg.txt mk.txt\
+- ml.txt mr.txt ms.txt mt.txt naq.txt\
+- nb.txt nd.txt ne.txt nl.txt nl_BE.txt\
+- nn.txt nyn.txt om.txt or.txt pa.txt\
+- pa_Arab.txt pa_Arab_PK.txt pa_Guru.txt pa_Guru_IN.txt pl.txt\
+- ps.txt pt.txt pt_PT.txt rm.txt ro.txt\
+- rof.txt ru.txt rw.txt rwk.txt saq.txt\
+- seh.txt ses.txt sg.txt shi.txt shi_Latn.txt\
+- shi_Latn_MA.txt shi_Tfng.txt si.txt sk.txt sl.txt\
+- sn.txt so.txt sq.txt sr.txt sr_Cyrl.txt\
+- sr_Cyrl_BA.txt sr_Cyrl_RS.txt sr_Latn.txt sr_Latn_BA.txt sr_Latn_ME.txt\
+- sr_Latn_RS.txt sv.txt sv_FI.txt sw.txt ta.txt\
+- te.txt teo.txt th.txt ti.txt to.txt\
+- tr.txt tzm.txt tzm_Latn.txt tzm_Latn_MA.txt uk.txt\
+- ur.txt uz.txt uz_Arab.txt uz_Arab_AF.txt uz_Cyrl.txt\
+- uz_Cyrl_UZ.txt uz_Latn.txt vi.txt vun.txt xog.txt\
+- yo.txt zh.txt zh_Hans.txt zh_Hans_CN.txt zh_Hans_SG.txt\
+- zh_Hant.txt zh_Hant_HK.txt zh_Hant_MO.txt zh_Hant_TW.txt zu.txt
+-
+diff -Naur a/source/data/sprep/sprepfiles.mk b/source/data/sprep/sprepfiles.mk
+--- a/source/data/sprep/sprepfiles.mk	2010-04-28 08:28:22.000000000 -0700
++++ b/source/data/sprep/sprepfiles.mk	1969-12-31 16:00:00.000000000 -0800
+@@ -1,27 +0,0 @@
+-# *   Copyright (C) 2009, International Business Machines
+-# *   Corporation and others.  All Rights Reserved.
+-# A list of txt's to build
+-# Note: 
+-#
+-#   If you are thinking of modifying this file, READ THIS. 
+-#
+-# Instead of changing this file [unless you want to check it back in],
+-# you should consider creating a 'brklocal.mk' file in this same directory.
+-# Then, you can have your local changes remain even if you upgrade or
+-# reconfigure ICU.
+-#
+-# Example 'spreplocal.mk' files:
+-#
+-#  * To add an additional locale to the list: 
+-#    _____________________________________________________
+-#    |  SPREP_SOURCE_LOCAL =   myStringPrep.txt ...
+-#
+-#  * To REPLACE the default list and only build a subset of files:
+-#    _____________________________________________________
+-#    |  SPREP_SOURCE = rfc4518.txt
+-#
+-#
+-SPREP_SOURCE = \
+-rfc3491.txt rfc3530cs.txt rfc3530csci.txt rfc3530mixp.txt rfc3722.txt \
+-rfc3920node.txt rfc3920res.txt rfc4011.txt rfc4013.txt rfc4505.txt \
+-rfc4518.txt rfc4518ci.txt
+diff -Naur a/source/data/translit/trnsfiles.mk b/source/data/translit/trnsfiles.mk
+--- a/source/data/translit/trnsfiles.mk	2010-04-28 08:28:26.000000000 -0700
++++ b/source/data/translit/trnsfiles.mk	1969-12-31 16:00:00.000000000 -0800
+@@ -1,26 +0,0 @@
+-# *   Copyright (C) 1997-2006, International Business Machines
+-# *   Corporation and others.  All Rights Reserved.
+-# A list of txt's to build
+-# Note: 
+-#
+-#   If you are thinking of modifying this file, READ THIS. 
+-#
+-# Instead of changing this file [unless you want to check it back in],
+-# you should consider creating a 'trnslocal.mk' file in this same directory.
+-# Then, you can have your local changes remain even if you upgrade or re
+-# configure the ICU.
+-#
+-# Example 'trnslocal.mk' files:
+-#
+-#  * To add an additional transliterators to the list: 
+-#    _____________________________________________________
+-#    |  TRANSLIT_SOURCE_LOCAL =   myTranslitRules.txt ...
+-#
+-#  * To REPLACE the default list and only build with a few
+-#     transliterators:
+-#    _____________________________________________________
+-#    |  TRANLIST_SOURCE = el.txt th.txt
+-#
+-#
+-
+-TRANSLIT_SOURCE=root.txt en.txt el.txt
+diff -Naur a/source/data/zone/resfiles.mk b/source/data/zone/resfiles.mk
+--- a/source/data/zone/resfiles.mk	2010-04-28 08:28:40.000000000 -0700
++++ b/source/data/zone/resfiles.mk	1969-12-31 16:00:00.000000000 -0800
+@@ -1,82 +0,0 @@
+-# *   Copyright (C) 1998-2010, International Business Machines
+-# *   Corporation and others.  All Rights Reserved.
+-ZONE_CLDR_VERSION = 1.8.1
+-# A list of txt's to build
+-# Note:
+-#
+-#   If you are thinking of modifying this file, READ THIS.
+-#
+-# Instead of changing this file [unless you want to check it back in],
+-# you should consider creating a 'reslocal.mk' file in this same directory.
+-# Then, you can have your local changes remain even if you upgrade or
+-# reconfigure ICU.
+-#
+-# Example 'reslocal.mk' files:
+-#
+-#  * To add an additional locale to the list:
+-#    _____________________________________________________
+-#    |  ZONE_SOURCE_LOCAL =   myLocale.txt ...
+-#
+-#  * To REPLACE the default list and only build with a few
+-#    locales:
+-#    _____________________________________________________
+-#    |  ZONE_SOURCE = ar.txt ar_AE.txt en.txt de.txt zh.txt
+-#
+-#
+-# Generated by LDML2ICUConverter, from LDML source files.
+-
+-# Aliases without a corresponding xx.xml file (see icu-config.xml & build.xml)
+-ZONE_SYNTHETIC_ALIAS = en_RH.txt he_IL.txt id_ID.txt in_ID.txt\
+- iw_IL.txt ja_JP.txt ja_JP_TRADITIONAL.txt nb_NO.txt nn_NO.txt\
+- no_NO.txt no_NO_NY.txt th_TH.txt th_TH_TRADITIONAL.txt
+-
+-
+-# All aliases (to not be included under 'installed'), but not including root.
+-ZONE_ALIAS_SOURCE = $(ZONE_SYNTHETIC_ALIAS) az_AZ.txt ha_GH.txt ha_NE.txt ha_NG.txt\
+- in.txt iw.txt kk_KZ.txt no.txt pa_IN.txt\
+- pa_PK.txt sh.txt sh_BA.txt sh_CS.txt sh_YU.txt\
+- shi_MA.txt sr_BA.txt sr_CS.txt sr_Cyrl_CS.txt sr_Cyrl_YU.txt\
+- sr_Latn_CS.txt sr_Latn_YU.txt sr_ME.txt sr_RS.txt sr_YU.txt\
+- tl.txt tzm_MA.txt uz_AF.txt uz_UZ.txt zh_CN.txt\
+- zh_HK.txt zh_MO.txt zh_SG.txt zh_TW.txt
+-
+-
+-# Ordinary resources
+-ZONE_SOURCE = af.txt ak.txt am.txt ar.txt\
+- as.txt asa.txt az.txt az_Cyrl.txt az_Latn.txt\
+- az_Latn_AZ.txt be.txt bem.txt bez.txt bg.txt\
+- bm.txt bn.txt bo.txt ca.txt cgg.txt\
+- chr.txt cs.txt cy.txt da.txt dav.txt\
+- de.txt ebu.txt ee.txt el.txt en.txt\
+- en_AU.txt en_CA.txt en_GB.txt en_NZ.txt en_ZA.txt\
+- en_ZW.txt eo.txt es.txt et.txt eu.txt\
+- fa.txt ff.txt fi.txt fil.txt fo.txt\
+- fr.txt fr_CA.txt ga.txt gl.txt gsw.txt\
+- gu.txt guz.txt gv.txt ha.txt ha_Latn.txt\
+- ha_Latn_GH.txt ha_Latn_NE.txt ha_Latn_NG.txt haw.txt he.txt\
+- hi.txt hr.txt hu.txt hy.txt id.txt\
+- ig.txt ii.txt is.txt it.txt ja.txt\
+- jmc.txt ka.txt kab.txt kam.txt kde.txt\
+- kea.txt khq.txt ki.txt kk.txt kk_Cyrl.txt\
+- kk_Cyrl_KZ.txt kl.txt kln.txt km.txt kn.txt\
+- ko.txt kok.txt kw.txt lag.txt lg.txt\
+- lt.txt luo.txt luy.txt lv.txt mas.txt\
+- mer.txt mfe.txt mg.txt mk.txt ml.txt\
+- mr.txt ms.txt mt.txt naq.txt nb.txt\
+- nd.txt ne.txt nl.txt nn.txt nyn.txt\
+- om.txt or.txt pa.txt pa_Arab.txt pa_Arab_PK.txt\
+- pa_Guru.txt pa_Guru_IN.txt pl.txt ps.txt pt.txt\
+- pt_PT.txt rm.txt ro.txt rof.txt ru.txt\
+- rw.txt rwk.txt saq.txt seh.txt ses.txt\
+- sg.txt shi.txt shi_Latn.txt shi_Latn_MA.txt shi_Tfng.txt\
+- si.txt sk.txt sl.txt sn.txt so.txt\
+- sq.txt sr.txt sr_Cyrl.txt sr_Cyrl_BA.txt sr_Cyrl_RS.txt\
+- sr_Latn.txt sr_Latn_BA.txt sr_Latn_ME.txt sr_Latn_RS.txt sv.txt\
+- sw.txt ta.txt te.txt teo.txt th.txt\
+- ti.txt to.txt tr.txt tzm.txt tzm_Latn.txt\
+- tzm_Latn_MA.txt uk.txt ur.txt uz.txt uz_Arab.txt\
+- uz_Arab_AF.txt uz_Cyrl.txt uz_Cyrl_UZ.txt uz_Latn.txt vi.txt\
+- vun.txt xog.txt yo.txt zh.txt zh_Hans.txt\
+- zh_Hans_CN.txt zh_Hans_SG.txt zh_Hant.txt zh_Hant_HK.txt zh_Hant_MO.txt\
+- zh_Hant_TW.txt zu.txt
+-
diff --git a/icu.patches/icu-56.description b/icu.patches/icu-56.description
new file mode 100644
index 0000000..7be2f4b
--- /dev/null
+++ b/icu.patches/icu-56.description
@@ -0,0 +1,2 @@
+To save on image size, strip out unused icu functionality.
+ICU User Guide talks about how to do this:  http://userguide.icu-project.org/packaging
diff --git a/icu.patches/icu-56.patch b/icu.patches/icu-56.patch
new file mode 100644
index 0000000..e9087d0
--- /dev/null
+++ b/icu.patches/icu-56.patch
@@ -0,0 +1,57 @@
+diff -Naur a/source/common/unicode/uconfig.h b/source/common/unicode/uconfig.h
+--- a/source/common/unicode/uconfig.h	2010-04-28 08:27:34.000000000 -0700
++++ b/source/common/unicode/uconfig.h	2015-07-23 13:05:07.489176056 -0700
+@@ -131,7 +131,7 @@
+  * @stable ICU 2.4
+  */
+ #ifndef UCONFIG_NO_LEGACY_CONVERSION
+-#   define UCONFIG_NO_LEGACY_CONVERSION 0
++#   define UCONFIG_NO_LEGACY_CONVERSION 1
+ #endif
+ 
+ /**
+@@ -163,7 +163,7 @@
+  * @stable ICU 2.4
+  */
+ #ifndef UCONFIG_NO_BREAK_ITERATION
+-#   define UCONFIG_NO_BREAK_ITERATION 0
++#   define UCONFIG_NO_BREAK_ITERATION 1
+ #endif
+ 
+ /**
+@@ -173,7 +173,7 @@
+  * @stable ICU 2.6
+  */
+ #ifndef UCONFIG_NO_IDNA
+-#   define UCONFIG_NO_IDNA 0
++#   define UCONFIG_NO_IDNA 1
+ #endif
+ 
+ /* i18n library switches ---------------------------------------------------- */
+@@ -205,7 +205,7 @@
+  * @stable ICU 2.4
+  */
+ #ifndef UCONFIG_NO_TRANSLITERATION
+-#   define UCONFIG_NO_TRANSLITERATION 0
++#   define UCONFIG_NO_TRANSLITERATION 1
+ #endif
+ 
+ /**
+@@ -215,7 +215,7 @@
+  * @stable ICU 2.4
+  */
+ #ifndef UCONFIG_NO_REGULAR_EXPRESSIONS
+-#   define UCONFIG_NO_REGULAR_EXPRESSIONS 0
++#   define UCONFIG_NO_REGULAR_EXPRESSIONS 1
+ #endif
+ 
+ /**
+@@ -225,7 +225,7 @@
+  * @stable ICU 3.2
+  */
+ #ifndef UCONFIG_NO_SERVICE
+-#   define UCONFIG_NO_SERVICE 0
++#   define UCONFIG_NO_SERVICE 1
+ #endif
+ 
+ #endif
diff --git a/icu.tar.gz b/icu.tar.gz
new file mode 100644
index 0000000..1ce2111
--- /dev/null
+++ b/icu.tar.gz
Binary files differ
diff --git a/icu.url b/icu.url
new file mode 100644
index 0000000..27d38f8
--- /dev/null
+++ b/icu.url
@@ -0,0 +1 @@
+http://download.icu-project.org/files/icu4c/4.4.1/icu4c-4_4_1-src.tgz
diff --git a/icu.version b/icu.version
new file mode 100644
index 0000000..cca25a9
--- /dev/null
+++ b/icu.version
@@ -0,0 +1 @@
+4.4.1
diff --git a/icu/APIChangeReport.html b/icu/APIChangeReport.html
new file mode 100644
index 0000000..445e11d
--- /dev/null
+++ b/icu/APIChangeReport.html
@@ -0,0 +1,3987 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+	 Copyright (C)  2010, International Business Machines Corporation, All Rights Reserved. 
+	--><html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>ICU4C API Comparison: 4.2.1 with 4.4 r27528:27535M</title>
+<link type="text/css" href="icu4c.css" rel="stylesheet">
+</head>
+<body>
+<a name="_top"></a>
+<h1>ICU4C API Comparison: 4.2.1 with 4.4 (r27528:27535M)</h1>
+<i>Note: This report compares ICU4C 4.4 (including 4.4.1) with the
+	 prevous major release (4.2.1). To see a report between
+         4.4 and 4.4.1, click here: <a href="APIChangeReport441.html">APIChangeReport441.html</a></i>
+<ul>
+<li>
+<a href="#removed">Removed from 4.2.1</a>
+</li>
+<li>
+<a href="#deprecated">Deprecated or Obsoleted in 4.4</a>
+</li>
+<li>
+<a href="#changed">Changed in  4.4</a>
+</li>
+<li>
+<a href="#promoted">Promoted to stable in 4.4</a>
+</li>
+<li>
+<a href="#added">Added in 4.4</a>
+</li>
+<li>
+<a href="#other">Other existing drafts in 4.4</a>
+</li>
+</ul>
+<hr>
+<a name="removed">
+<h2>Removed from 4.2.1</h2>
+</a>
+<table BORDER="1" class="genTable">
+<THEAD>
+<tr>
+<th>File</th><th>API</th><th>4.2.1</th><th>4.4</th>
+</tr>
+</THEAD>
+<tr class="row1">
+<td class="file">decimfmt.h</td><td class="proto">UBool decimfmtAffixPatternValueComparator(UHashTok, UHashTok)</td><td class="">Internal<br>4.2</td><td>None<br>
+<span class=""><span></span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">decimfmt.h</td><td class="proto">UBool decimfmtAffixValueComparator(UHashTok, UHashTok)</td><td class="">Internal<br>4.2</td><td>None<br>
+<span class=""><span></span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">dtitvinf.h</td><td class="proto">UBool dtitvinfHashTableValueComparator(UHashTok, UHashTok)</td><td class="">Internal<br>4.0</td><td>None<br>
+<span class=""><span></span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">errorcode.h</td><td class="proto">void ErrorCode::check() const</td><td class="">Draft<br>4.2</td><td>None<br>
+<span class=""><span></span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">pwin32.h</td><td class="proto">#define ICU_USE_THREADS</td><td class="">
+<br>
+</td><td>None<br>
+<span class=""><span></span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">pwin32.h</td><td class="proto">#define U_HAVE_LIB_SUFFIX</td><td class="">
+<br>
+</td><td>None<br>
+<span class=""><span></span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">pwin32.h</td><td class="proto">#define U_LIB_SUFFIX_C_NAME_STRING</td><td class="">
+<br>
+</td><td>None<br>
+<span class=""><span></span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">pwin32.h</td><td class="proto">#define U_LIB_SUFFIX_C_NAME</td><td class="">
+<br>
+</td><td>None<br>
+<span class=""><span></span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">tmutfmt.h</td><td class="proto">static UBool hashTableValueComparator(UHashTok, UHashTok)</td><td class="">Internal<br>4.2</td><td>None<br>
+<span class=""><span></span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">uversion.h</td><td class="proto">int32_t u_compareVersions(UVersionInfo, UVersionInfo)</td><td class="">Draft<br>4.2</td><td>None<br>
+<span class=""><span></span></span></td>
+</tr>
+</table>
+<P></P>
+<a href="#_top">(jump back to top)</a>
+<hr>
+<a name="deprecated">
+<h2>Deprecated or Obsoleted in 4.4</h2>
+</a>
+<table BORDER="1" class="genTable">
+<THEAD>
+<tr>
+<th>File</th><th>API</th><th>4.2.1</th><th>4.4</th>
+</tr>
+</THEAD>
+</table>
+<P></P>
+<a href="#_top">(jump back to top)</a>
+<hr>
+<a name="changed">
+<h2>Changed in  4.4 (old, new)</h2>
+</a>
+<table BORDER="1" class="genTable">
+<THEAD>
+<tr>
+<th>File</th><th>API</th><th>4.2.1</th><th>4.4</th>
+</tr>
+</THEAD>
+<tr class="row1">
+<td class="file">bms.h</td><td class="proto">void bms_close(BMS*)</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>4.0.1 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">bmsearch.h</td><td class="proto">UClassID BoyerMooreSearch::getDynamicClassID() const</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>4.0.1 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">bmsearch.h</td><td class="proto">static UClassID BoyerMooreSearch::getStaticClassID()</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>4.0.1 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">bytestream.h</td><td class="proto">ByteSink::ByteSink()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">bytestream.h</td><td class="proto">ByteSink::~ByteSink()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">bytestream.h</td><td class="proto">CheckedArrayByteSink::CheckedArrayByteSink(char*, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">bytestream.h</td><td class="proto">StringByteSink&lt; StringClass &gt;::StringByteSink(StringClass*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">bytestream.h</td><td class="proto">UBool CheckedArrayByteSink::Overflowed() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">bytestream.h</td><td class="proto">char* ByteSink::GetAppendBuffer(int32_t, int32_t, char*, int32_t, int32_t*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">bytestream.h</td><td class="proto">char* CheckedArrayByteSink::GetAppendBuffer(int32_t, int32_t, char*, int32_t, int32_t*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">bytestream.h</td><td class="proto">int32_t CheckedArrayByteSink::NumberOfBytesWritten() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">bytestream.h</td><td class="proto">void ByteSink::Append(const char*, int32_t)=0</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">bytestream.h</td><td class="proto">void ByteSink::Flush()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">bytestream.h</td><td class="proto">void CheckedArrayByteSink::Append(const char*, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">bytestream.h</td><td class="proto">void StringByteSink&lt; StringClass &gt;::Append(const char*, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">calendar.h</td><td class="proto">static StringEnumeration* Calendar::getKeywordValuesForLocale(const char*, const Locale&amp;, UBool, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">coll.h</td><td class="proto">UCollationResult Collator::compare(UCharIterator&amp;, UCharIterator&amp;, UErrorCode&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">coll.h</td><td class="proto">UCollationResult Collator::compareUTF8(const StringPiece&amp;, const StringPiece&amp;, UErrorCode&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">coll.h</td><td class="proto">static StringEnumeration* Collator::getKeywordValuesForLocale(const char*, const Locale&amp;, UBool, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">colldata.h</td><td class="proto">#define CELIST_BUFFER_SIZE</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>4.0.1 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">colldata.h</td><td class="proto">#define KEY_BUFFER_SIZE</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>4.0.1 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">colldata.h</td><td class="proto">#define STRING_LIST_BUFFER_SIZE</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>4.0.1 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">colldata.h</td><td class="proto">CEList::~CEList()</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>4.0.1 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">colldata.h</td><td class="proto">UClassID CEList::getDynamicClassID() const</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>4.0.1 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">colldata.h</td><td class="proto">UClassID CollData::getDynamicClassID() const</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>4.0.1 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">colldata.h</td><td class="proto">UClassID StringList::getDynamicClassID() const</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>4.0.1 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">colldata.h</td><td class="proto">UCollator* CollData::getCollator() const</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>4.0.1 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">colldata.h</td><td class="proto">static UClassID CEList::getStaticClassID()</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>4.0.1 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">colldata.h</td><td class="proto">static UClassID CollData::getStaticClassID()</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>4.0.1 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">colldata.h</td><td class="proto">static UClassID StringList::getStaticClassID()</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>4.0.1 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">CurrencyPluralInfo&amp; CurrencyPluralInfo::operator=(const CurrencyPluralInfo&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">CurrencyPluralInfo* CurrencyPluralInfo::clone() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">CurrencyPluralInfo::CurrencyPluralInfo(UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">CurrencyPluralInfo::CurrencyPluralInfo(const CurrencyPluralInfo&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">CurrencyPluralInfo::CurrencyPluralInfo(const Locale&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">CurrencyPluralInfo::~CurrencyPluralInfo()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">UBool CurrencyPluralInfo::operator!=(const CurrencyPluralInfo&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">UBool CurrencyPluralInfo::operator==(const CurrencyPluralInfo&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">UClassID CurrencyPluralInfo::getDynamicClassID() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">UnicodeString&amp; CurrencyPluralInfo::getCurrencyPluralPattern(const UnicodeString&amp;, UnicodeString&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">const Locale&amp; CurrencyPluralInfo::getLocale() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">const PluralRules* CurrencyPluralInfo::getPluralRules() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">static UClassID CurrencyPluralInfo::getStaticClassID()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">void CurrencyPluralInfo::setCurrencyPluralPattern(const UnicodeString&amp;, const UnicodeString&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">void CurrencyPluralInfo::setLocale(const Locale&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">void CurrencyPluralInfo::setPluralRules(const UnicodeString&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">decimfmt.h</td><td class="proto">const CurrencyPluralInfo* DecimalFormat::getCurrencyPluralInfo()const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">decimfmt.h</td><td class="proto">void DecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">decimfmt.h</td><td class="proto">void DecimalFormat::setCurrencyPluralInfo(const CurrencyPluralInfo&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">dtfmtsym.h</td><td class="proto">const UnicodeString* DateFormatSymbols::getNarrowEras(int32_t&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">dtfmtsym.h</td><td class="proto">void DateFormatSymbols::setNarrowEras(const UnicodeString*, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">errorcode.h</td><td class="proto">ErrorCode::ErrorCode()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">errorcode.h</td><td class="proto">ErrorCode::operator UErrorCode &amp;()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">errorcode.h</td><td class="proto">ErrorCode::operator UErrorCode *()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">errorcode.h</td><td class="proto">ErrorCode::~ErrorCode()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">errorcode.h</td><td class="proto">UBool ErrorCode::isFailure() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">errorcode.h</td><td class="proto">UBool ErrorCode::isSuccess() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">errorcode.h</td><td class="proto">UErrorCode ErrorCode::get() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">errorcode.h</td><td class="proto">UErrorCode ErrorCode::reset()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">errorcode.h</td><td class="proto">void ErrorCode::set(UErrorCode)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">LEGlyphStorage.h</td><td class="proto">LEGlyphID* LEGlyphStorage::insertGlyphs(le_int32, le_int32, LEErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">LEGlyphStorage.h</td><td class="proto">void LEGlyphStorage::moveGlyph(le_int32, le_int32, le_uint32)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numsys.h</td><td class="proto">NumberingSystem::NumberingSystem()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">numsys.h</td><td class="proto">NumberingSystem::NumberingSystem(const NumberingSystem&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numsys.h</td><td class="proto">NumberingSystem::~NumberingSystem()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">numsys.h</td><td class="proto">UBool NumberingSystem::isAlgorithmic() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numsys.h</td><td class="proto">UClassID NumberingSystem::getDynamicClassID() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">numsys.h</td><td class="proto">UnicodeString NumberingSystem::getDescription()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numsys.h</td><td class="proto">int32_t NumberingSystem::getRadix()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">numsys.h</td><td class="proto">static NumberingSystem* NumberingSystem::createInstance(UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numsys.h</td><td class="proto">static NumberingSystem* NumberingSystem::createInstance(const Locale&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">numsys.h</td><td class="proto">static NumberingSystem* NumberingSystem::createInstance(int32_t, UBool, const UnicodeString&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numsys.h</td><td class="proto">static NumberingSystem* NumberingSystem::createInstanceByName(const char*, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">numsys.h</td><td class="proto">static StringEnumeration* NumberingSystem::getAvailableNames(UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numsys.h</td><td class="proto">static UClassID NumberingSystem::getStaticClassID()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">platform.h</td><td class="proto">#define U_HAVE_DIRENT_H</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">platform.h</td><td class="proto">#define U_HAVE_LIB_SUFFIX</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">platform.h</td><td class="proto">#define U_LIB_SUFFIX_C_NAME_STRING</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">platform.h</td><td class="proto">#define U_LIB_SUFFIX_C_NAME</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">pwin32.h</td><td class="proto">#define U_DAYLIGHT</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">pwin32.h</td><td class="proto">#define U_TIMEZONE</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">pwin32.h</td><td class="proto">#define U_TZNAME</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">pwin32.h</td><td class="proto">#define U_TZSET</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">smpdtfmt.h</td><td class="proto">SimpleDateFormat::SimpleDateFormat(const UnicodeString&amp;, const UnicodeString&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">smpdtfmt.h</td><td class="proto">SimpleDateFormat::SimpleDateFormat(const UnicodeString&amp;, const UnicodeString&amp;, const Locale&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">stringpiece.h</td><td class="proto">StringPiece StringPiece::substr(int32_t, int32_t len=) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">stringpiece.h</td><td class="proto">StringPiece::StringPiece()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">stringpiece.h</td><td class="proto">StringPiece::StringPiece(const StringPiece&amp;, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">stringpiece.h</td><td class="proto">StringPiece::StringPiece(const StringPiece&amp;, int32_t, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">stringpiece.h</td><td class="proto">StringPiece::StringPiece(const U_STD_NSQ string&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">stringpiece.h</td><td class="proto">StringPiece::StringPiece(const char*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">stringpiece.h</td><td class="proto">StringPiece::StringPiece(const char*, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">stringpiece.h</td><td class="proto">UBool StringPiece::empty() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">stringpiece.h</td><td class="proto">const char* StringPiece::data() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">stringpiece.h</td><td class="proto">int32_t StringPiece::length() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">stringpiece.h</td><td class="proto">int32_t StringPiece::size() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">stringpiece.h</td><td class="proto">void StringPiece::clear()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">stringpiece.h</td><td class="proto">void StringPiece::remove_prefix(int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">stringpiece.h</td><td class="proto">void StringPiece::remove_suffix(int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tblcoll.h</td><td class="proto">UCollationResult RuleBasedCollator::compare(UCharIterator&amp;, UCharIterator&amp;, UErrorCode&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmunit.h</td><td class="proto">TimeUnit&amp; TimeUnit::operator=(const TimeUnit&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmunit.h</td><td class="proto">TimeUnit::TimeUnit(const TimeUnit&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmunit.h</td><td class="proto">TimeUnit::~TimeUnit()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmunit.h</td><td class="proto">UBool TimeUnit::operator!=(const UObject&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmunit.h</td><td class="proto">UBool TimeUnit::operator==(const UObject&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmunit.h</td><td class="proto">UClassID TimeUnit::getDynamicClassID() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmunit.h</td><td class="proto">UObject* TimeUnit::clone() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmunit.h</td><td class="proto">UTimeUnitFields TimeUnit::getTimeUnitField() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmunit.h</td><td class="proto">static TimeUnit* TimeUnit::createInstance(UTimeUnitFields, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmunit.h</td><td class="proto">static UClassID TimeUnit::getStaticClassID()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutamt.h</td><td class="proto">TimeUnit::UTimeUnitFields TimeUnitAmount::getTimeUnitField() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutamt.h</td><td class="proto">TimeUnitAmount&amp; TimeUnitAmount::operator=(const TimeUnitAmount&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutamt.h</td><td class="proto">TimeUnitAmount::TimeUnitAmount(const Formattable&amp;, TimeUnit::UTimeUnitFields, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutamt.h</td><td class="proto">TimeUnitAmount::TimeUnitAmount(const TimeUnitAmount&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutamt.h</td><td class="proto">TimeUnitAmount::TimeUnitAmount(double, TimeUnit::UTimeUnitFields, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutamt.h</td><td class="proto">TimeUnitAmount::~TimeUnitAmount()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutamt.h</td><td class="proto">UBool TimeUnitAmount::operator!=(const UObject&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutamt.h</td><td class="proto">UBool TimeUnitAmount::operator==(const UObject&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutamt.h</td><td class="proto">UClassID TimeUnitAmount::getDynamicClassID()const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutamt.h</td><td class="proto">UObject* TimeUnitAmount::clone() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutamt.h</td><td class="proto">const TimeUnit&amp; TimeUnitAmount::getTimeUnit() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutamt.h</td><td class="proto">static UClassID TimeUnitAmount::getStaticClassID()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutfmt.h</td><td class="proto">Format* TimeUnitFormat::clone()const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">TimeUnitFormat&amp; TimeUnitFormat::operator=(const TimeUnitFormat&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutfmt.h</td><td class="proto">TimeUnitFormat::TimeUnitFormat(UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">TimeUnitFormat::TimeUnitFormat(const Locale&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutfmt.h</td><td class="proto">TimeUnitFormat::TimeUnitFormat(const TimeUnitFormat&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">TimeUnitFormat::~TimeUnitFormat()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutfmt.h</td><td class="proto">UBool TimeUnitFormat::operator!=(const Format&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">UBool TimeUnitFormat::operator==(const Format&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutfmt.h</td><td class="proto">UClassID TimeUnitFormat::getDynamicClassID()const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">UnicodeString&amp; TimeUnitFormat::format(const Formattable&amp;, UnicodeString&amp;, FieldPosition&amp;, UErrorCode&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutfmt.h</td><td class="proto">static UClassID TimeUnitFormat::getStaticClassID()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">void TimeUnitFormat::parseObject(const UnicodeString&amp;, Formattable&amp;, ParsePosition&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutfmt.h</td><td class="proto">void TimeUnitFormat::setLocale(const Locale&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">void TimeUnitFormat::setNumberFormat(const NumberFormat&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ucal.h</td><td class="proto">UEnumeration* ucal_getKeywordValuesForLocale(const char*, const char*, UBool, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ucal.h</td><td class="proto">const char* ucal_getType(const UCalendar*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ucnvsel.h</td><td class="proto">UConverterSelector* ucnvsel_open(const char*const*, int32_t, const USet*, const UConverterUnicodeSet, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ucnvsel.h</td><td class="proto">UConverterSelector* ucnvsel_openFromSerialized(const void*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ucnvsel.h</td><td class="proto">UEnumeration* ucnvsel_selectForString(const UConverterSelector*, const UChar*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ucnvsel.h</td><td class="proto">UEnumeration* ucnvsel_selectForUTF8(const UConverterSelector*, const char*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ucnvsel.h</td><td class="proto">int32_t ucnvsel_serialize(const UConverterSelector*, void*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ucnvsel.h</td><td class="proto">void ucnvsel_close(UConverterSelector*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ucol.h</td><td class="proto">UEnumeration* ucol_getKeywordValuesForLocale(const char*, const char*, UBool, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ucurr.h</td><td class="proto">UEnumeration* ucurr_getKeywordValuesForLocale(const char*, const char*, UBool, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ucurr.h</td><td class="proto">const UChar* ucurr_getPluralName(const UChar*, const char*, UBool*, const char*, int32_t*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">udat.h</td><td class="proto">#define UDAT_HOUR_MINUTE</td><td class="">
+<br>
+</td><td>Stable<br>
+<span class=""><span>4.0</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ulocdata.h</td><td class="proto">int32_t ulocdata_getLocaleDisplayPattern(ULocaleData*, UChar*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ulocdata.h</td><td class="proto">int32_t ulocdata_getLocaleSeparator(ULocaleData*, UChar*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ulocdata.h</td><td class="proto">void ulocdata_getCLDRVersion(UVersionInfo, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">umachine.h</td><td class="proto">#define U_ATTRIBUTE_DEPRECATED</td><td class="">
+<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">uniset.h</td><td class="proto">USet * UnicodeSet::toUSet()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uniset.h</td><td class="proto">UnicodeSet&amp; UnicodeSet::closeOver(int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uniset.h</td><td class="proto">UnicodeSet&amp; UnicodeSet::removeAllStrings()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uniset.h</td><td class="proto">const USet * UnicodeSet::toUSet() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uniset.h</td><td class="proto">static UnicodeSet* UnicodeSet::fromUSet(USet*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uniset.h</td><td class="proto">static const UnicodeSet* UnicodeSet::fromUSet(const USet*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">unistr.h</td><td class="proto">StringClass&amp; UnicodeString::toUTF8String(StringClass&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">unistr.h</td><td class="proto">int32_t UnicodeString::toUTF32(UChar32*, int32_t, UErrorCode&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">unistr.h</td><td class="proto">static UnicodeString UnicodeString::fromUTF32(const UChar32*, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">unistr.h</td><td class="proto">static UnicodeString UnicodeString::fromUTF8(const StringPiece&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">unistr.h</td><td class="proto">void UnicodeString::toUTF8(ByteSink&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uset.h</td><td class="proto">USet* uset_openEmpty()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uset.h</td><td class="proto">void uset_closeOver(USet*, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uset.h</td><td class="proto">void uset_removeAllStrings(USet*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define SHAPE_TAIL_NEW_UNICODE</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define SHAPE_TAIL_TYPE_MASK</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_AUTO</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_BEGIN</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_END</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_MASK</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_NEAR</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_RESIZE</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_SEEN_MASK</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_SEEN_TWOCELL_NEAR</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_SPACES_RELATIVE_TO_TEXT_BEGIN_END</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_SPACES_RELATIVE_TO_TEXT_MASK</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TASHKEEL_BEGIN</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TASHKEEL_END</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TASHKEEL_MASK</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TASHKEEL_REPLACE_BY_TATWEEL</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TASHKEEL_RESIZE</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TEXT_DIRECTION_VISUAL_RTL</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_YEHHAMZA_MASK</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_YEHHAMZA_TWOCELL_NEAR</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">USpoofChecker* uspoof_clone(const USpoofChecker*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">USpoofChecker* uspoof_open(UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">USpoofChecker* uspoof_openFromSerialized(const void*, int32_t, int32_t*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">USpoofChecker* uspoof_openFromSource(const char*, int32_t, const char*, int32_t, int32_t*, UParseError*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">const USet* uspoof_getAllowedChars(const USpoofChecker*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">const char* uspoof_getAllowedLocales(USpoofChecker*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_areConfusable(const USpoofChecker*, const UChar*, int32_t, const UChar*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_areConfusableUTF8(const USpoofChecker*, const char*, int32_t, const char*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_check(const USpoofChecker*, const UChar*, int32_t, int32_t*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_checkUTF8(const USpoofChecker*, const char*, int32_t, int32_t*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_getChecks(const USpoofChecker*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_getSkeleton(const USpoofChecker*, uint32_t, const UChar*, int32_t, UChar*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_getSkeletonUTF8(const USpoofChecker*, uint32_t, const char*, int32_t, char*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_serialize(USpoofChecker*, void*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">void uspoof_close(USpoofChecker*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">void uspoof_setAllowedChars(USpoofChecker*, const USet*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">void uspoof_setAllowedLocales(USpoofChecker*, const char*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">void uspoof_setChecks(USpoofChecker*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">usprep.h</td><td class="proto">UStringPrepProfile* usprep_openByType(UStringPrepProfileType, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ustring.h</td><td class="proto">UChar* u_strFromUTF32WithSub(UChar*, int32_t, int32_t*, const UChar32*, int32_t, UChar32, int32_t*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ustring.h</td><td class="proto">UChar32* u_strToUTF32WithSub(UChar32*, int32_t, int32_t*, const UChar*, int32_t, UChar32, int32_t*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uversion.h</td><td class="proto">void u_versionFromUString(UVersionInfo, const UChar*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+</table>
+<P></P>
+<a href="#_top">(jump back to top)</a>
+<hr>
+<a name="promoted">
+<h2>Promoted to stable in 4.4</h2>
+</a>
+<table BORDER="1" class="genTable">
+<THEAD>
+<tr>
+<th>File</th><th>API</th><th>4.2.1</th><th>4.4</th>
+</tr>
+</THEAD>
+<tr class="row1">
+<td class="file">bytestream.h</td><td class="proto">ByteSink::ByteSink()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">bytestream.h</td><td class="proto">ByteSink::~ByteSink()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">bytestream.h</td><td class="proto">CheckedArrayByteSink::CheckedArrayByteSink(char*, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">bytestream.h</td><td class="proto">StringByteSink&lt; StringClass &gt;::StringByteSink(StringClass*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">bytestream.h</td><td class="proto">UBool CheckedArrayByteSink::Overflowed() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">bytestream.h</td><td class="proto">char* ByteSink::GetAppendBuffer(int32_t, int32_t, char*, int32_t, int32_t*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">bytestream.h</td><td class="proto">char* CheckedArrayByteSink::GetAppendBuffer(int32_t, int32_t, char*, int32_t, int32_t*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">bytestream.h</td><td class="proto">int32_t CheckedArrayByteSink::NumberOfBytesWritten() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">bytestream.h</td><td class="proto">void ByteSink::Append(const char*, int32_t)=0</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">bytestream.h</td><td class="proto">void ByteSink::Flush()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">bytestream.h</td><td class="proto">void CheckedArrayByteSink::Append(const char*, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">bytestream.h</td><td class="proto">void StringByteSink&lt; StringClass &gt;::Append(const char*, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">calendar.h</td><td class="proto">static StringEnumeration* Calendar::getKeywordValuesForLocale(const char*, const Locale&amp;, UBool, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">coll.h</td><td class="proto">UCollationResult Collator::compare(UCharIterator&amp;, UCharIterator&amp;, UErrorCode&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">coll.h</td><td class="proto">UCollationResult Collator::compareUTF8(const StringPiece&amp;, const StringPiece&amp;, UErrorCode&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">coll.h</td><td class="proto">static StringEnumeration* Collator::getKeywordValuesForLocale(const char*, const Locale&amp;, UBool, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">CurrencyPluralInfo&amp; CurrencyPluralInfo::operator=(const CurrencyPluralInfo&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">CurrencyPluralInfo* CurrencyPluralInfo::clone() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">CurrencyPluralInfo::CurrencyPluralInfo(UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">CurrencyPluralInfo::CurrencyPluralInfo(const CurrencyPluralInfo&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">CurrencyPluralInfo::CurrencyPluralInfo(const Locale&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">CurrencyPluralInfo::~CurrencyPluralInfo()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">UBool CurrencyPluralInfo::operator!=(const CurrencyPluralInfo&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">UBool CurrencyPluralInfo::operator==(const CurrencyPluralInfo&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">UClassID CurrencyPluralInfo::getDynamicClassID() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">UnicodeString&amp; CurrencyPluralInfo::getCurrencyPluralPattern(const UnicodeString&amp;, UnicodeString&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">const Locale&amp; CurrencyPluralInfo::getLocale() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">const PluralRules* CurrencyPluralInfo::getPluralRules() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">static UClassID CurrencyPluralInfo::getStaticClassID()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">void CurrencyPluralInfo::setCurrencyPluralPattern(const UnicodeString&amp;, const UnicodeString&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">currpinf.h</td><td class="proto">void CurrencyPluralInfo::setLocale(const Locale&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">currpinf.h</td><td class="proto">void CurrencyPluralInfo::setPluralRules(const UnicodeString&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">decimfmt.h</td><td class="proto">const CurrencyPluralInfo* DecimalFormat::getCurrencyPluralInfo()const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">decimfmt.h</td><td class="proto">void DecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">decimfmt.h</td><td class="proto">void DecimalFormat::setCurrencyPluralInfo(const CurrencyPluralInfo&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">dtfmtsym.h</td><td class="proto">const UnicodeString* DateFormatSymbols::getNarrowEras(int32_t&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">dtfmtsym.h</td><td class="proto">void DateFormatSymbols::setNarrowEras(const UnicodeString*, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">errorcode.h</td><td class="proto">ErrorCode::ErrorCode()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">errorcode.h</td><td class="proto">ErrorCode::operator UErrorCode &amp;()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">errorcode.h</td><td class="proto">ErrorCode::operator UErrorCode *()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">errorcode.h</td><td class="proto">ErrorCode::~ErrorCode()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">errorcode.h</td><td class="proto">UBool ErrorCode::isFailure() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">errorcode.h</td><td class="proto">UBool ErrorCode::isSuccess() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">errorcode.h</td><td class="proto">UErrorCode ErrorCode::get() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">errorcode.h</td><td class="proto">UErrorCode ErrorCode::reset()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">errorcode.h</td><td class="proto">void ErrorCode::set(UErrorCode)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">LEGlyphStorage.h</td><td class="proto">LEGlyphID* LEGlyphStorage::insertGlyphs(le_int32, le_int32, LEErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">LEGlyphStorage.h</td><td class="proto">void LEGlyphStorage::moveGlyph(le_int32, le_int32, le_uint32)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numsys.h</td><td class="proto">NumberingSystem::NumberingSystem()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">numsys.h</td><td class="proto">NumberingSystem::NumberingSystem(const NumberingSystem&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numsys.h</td><td class="proto">NumberingSystem::~NumberingSystem()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">numsys.h</td><td class="proto">UBool NumberingSystem::isAlgorithmic() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numsys.h</td><td class="proto">UClassID NumberingSystem::getDynamicClassID() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">numsys.h</td><td class="proto">UnicodeString NumberingSystem::getDescription()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numsys.h</td><td class="proto">int32_t NumberingSystem::getRadix()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">numsys.h</td><td class="proto">static NumberingSystem* NumberingSystem::createInstance(UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numsys.h</td><td class="proto">static NumberingSystem* NumberingSystem::createInstance(const Locale&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">numsys.h</td><td class="proto">static NumberingSystem* NumberingSystem::createInstance(int32_t, UBool, const UnicodeString&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numsys.h</td><td class="proto">static NumberingSystem* NumberingSystem::createInstanceByName(const char*, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">numsys.h</td><td class="proto">static StringEnumeration* NumberingSystem::getAvailableNames(UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numsys.h</td><td class="proto">static UClassID NumberingSystem::getStaticClassID()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">smpdtfmt.h</td><td class="proto">SimpleDateFormat::SimpleDateFormat(const UnicodeString&amp;, const UnicodeString&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">smpdtfmt.h</td><td class="proto">SimpleDateFormat::SimpleDateFormat(const UnicodeString&amp;, const UnicodeString&amp;, const Locale&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">stringpiece.h</td><td class="proto">StringPiece StringPiece::substr(int32_t, int32_t len=) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">stringpiece.h</td><td class="proto">StringPiece::StringPiece()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">stringpiece.h</td><td class="proto">StringPiece::StringPiece(const StringPiece&amp;, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">stringpiece.h</td><td class="proto">StringPiece::StringPiece(const StringPiece&amp;, int32_t, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">stringpiece.h</td><td class="proto">StringPiece::StringPiece(const U_STD_NSQ string&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">stringpiece.h</td><td class="proto">StringPiece::StringPiece(const char*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">stringpiece.h</td><td class="proto">StringPiece::StringPiece(const char*, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">stringpiece.h</td><td class="proto">UBool StringPiece::empty() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">stringpiece.h</td><td class="proto">const char* StringPiece::data() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">stringpiece.h</td><td class="proto">int32_t StringPiece::length() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">stringpiece.h</td><td class="proto">int32_t StringPiece::size() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">stringpiece.h</td><td class="proto">void StringPiece::clear()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">stringpiece.h</td><td class="proto">void StringPiece::remove_prefix(int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">stringpiece.h</td><td class="proto">void StringPiece::remove_suffix(int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tblcoll.h</td><td class="proto">UCollationResult RuleBasedCollator::compare(UCharIterator&amp;, UCharIterator&amp;, UErrorCode&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmunit.h</td><td class="proto">TimeUnit&amp; TimeUnit::operator=(const TimeUnit&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmunit.h</td><td class="proto">TimeUnit::TimeUnit(const TimeUnit&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmunit.h</td><td class="proto">TimeUnit::~TimeUnit()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmunit.h</td><td class="proto">UBool TimeUnit::operator!=(const UObject&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmunit.h</td><td class="proto">UBool TimeUnit::operator==(const UObject&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmunit.h</td><td class="proto">UClassID TimeUnit::getDynamicClassID() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmunit.h</td><td class="proto">UObject* TimeUnit::clone() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmunit.h</td><td class="proto">UTimeUnitFields TimeUnit::getTimeUnitField() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmunit.h</td><td class="proto">static TimeUnit* TimeUnit::createInstance(UTimeUnitFields, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmunit.h</td><td class="proto">static UClassID TimeUnit::getStaticClassID()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutamt.h</td><td class="proto">TimeUnit::UTimeUnitFields TimeUnitAmount::getTimeUnitField() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutamt.h</td><td class="proto">TimeUnitAmount&amp; TimeUnitAmount::operator=(const TimeUnitAmount&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutamt.h</td><td class="proto">TimeUnitAmount::TimeUnitAmount(const Formattable&amp;, TimeUnit::UTimeUnitFields, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutamt.h</td><td class="proto">TimeUnitAmount::TimeUnitAmount(const TimeUnitAmount&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutamt.h</td><td class="proto">TimeUnitAmount::TimeUnitAmount(double, TimeUnit::UTimeUnitFields, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutamt.h</td><td class="proto">TimeUnitAmount::~TimeUnitAmount()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutamt.h</td><td class="proto">UBool TimeUnitAmount::operator!=(const UObject&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutamt.h</td><td class="proto">UBool TimeUnitAmount::operator==(const UObject&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutamt.h</td><td class="proto">UClassID TimeUnitAmount::getDynamicClassID()const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutamt.h</td><td class="proto">UObject* TimeUnitAmount::clone() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutamt.h</td><td class="proto">const TimeUnit&amp; TimeUnitAmount::getTimeUnit() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutamt.h</td><td class="proto">static UClassID TimeUnitAmount::getStaticClassID()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutfmt.h</td><td class="proto">Format* TimeUnitFormat::clone()const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">TimeUnitFormat&amp; TimeUnitFormat::operator=(const TimeUnitFormat&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutfmt.h</td><td class="proto">TimeUnitFormat::TimeUnitFormat(UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">TimeUnitFormat::TimeUnitFormat(const Locale&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutfmt.h</td><td class="proto">TimeUnitFormat::TimeUnitFormat(const TimeUnitFormat&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">TimeUnitFormat::~TimeUnitFormat()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutfmt.h</td><td class="proto">UBool TimeUnitFormat::operator!=(const Format&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">UBool TimeUnitFormat::operator==(const Format&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutfmt.h</td><td class="proto">UClassID TimeUnitFormat::getDynamicClassID()const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">UnicodeString&amp; TimeUnitFormat::format(const Formattable&amp;, UnicodeString&amp;, FieldPosition&amp;, UErrorCode&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutfmt.h</td><td class="proto">static UClassID TimeUnitFormat::getStaticClassID()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">void TimeUnitFormat::parseObject(const UnicodeString&amp;, Formattable&amp;, ParsePosition&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">tmutfmt.h</td><td class="proto">void TimeUnitFormat::setLocale(const Locale&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">void TimeUnitFormat::setNumberFormat(const NumberFormat&amp;, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ucal.h</td><td class="proto">UEnumeration* ucal_getKeywordValuesForLocale(const char*, const char*, UBool, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ucal.h</td><td class="proto">const char* ucal_getType(const UCalendar*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ucnvsel.h</td><td class="proto">UConverterSelector* ucnvsel_open(const char*const*, int32_t, const USet*, const UConverterUnicodeSet, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ucnvsel.h</td><td class="proto">UConverterSelector* ucnvsel_openFromSerialized(const void*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ucnvsel.h</td><td class="proto">UEnumeration* ucnvsel_selectForString(const UConverterSelector*, const UChar*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ucnvsel.h</td><td class="proto">UEnumeration* ucnvsel_selectForUTF8(const UConverterSelector*, const char*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ucnvsel.h</td><td class="proto">int32_t ucnvsel_serialize(const UConverterSelector*, void*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ucnvsel.h</td><td class="proto">void ucnvsel_close(UConverterSelector*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ucol.h</td><td class="proto">UEnumeration* ucol_getKeywordValuesForLocale(const char*, const char*, UBool, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ucurr.h</td><td class="proto">UEnumeration* ucurr_getKeywordValuesForLocale(const char*, const char*, UBool, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ucurr.h</td><td class="proto">const UChar* ucurr_getPluralName(const UChar*, const char*, UBool*, const char*, int32_t*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">udat.h</td><td class="proto">#define UDAT_HOUR_MINUTE</td><td class="">
+<br>
+</td><td>Stable<br>
+<span class=""><span>4.0</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ulocdata.h</td><td class="proto">int32_t ulocdata_getLocaleDisplayPattern(ULocaleData*, UChar*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ulocdata.h</td><td class="proto">int32_t ulocdata_getLocaleSeparator(ULocaleData*, UChar*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ulocdata.h</td><td class="proto">void ulocdata_getCLDRVersion(UVersionInfo, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uniset.h</td><td class="proto">USet * UnicodeSet::toUSet()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uniset.h</td><td class="proto">UnicodeSet&amp; UnicodeSet::closeOver(int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uniset.h</td><td class="proto">UnicodeSet&amp; UnicodeSet::removeAllStrings()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uniset.h</td><td class="proto">const USet * UnicodeSet::toUSet() const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uniset.h</td><td class="proto">static UnicodeSet* UnicodeSet::fromUSet(USet*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uniset.h</td><td class="proto">static const UnicodeSet* UnicodeSet::fromUSet(const USet*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">unistr.h</td><td class="proto">StringClass&amp; UnicodeString::toUTF8String(StringClass&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">unistr.h</td><td class="proto">int32_t UnicodeString::toUTF32(UChar32*, int32_t, UErrorCode&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">unistr.h</td><td class="proto">static UnicodeString UnicodeString::fromUTF32(const UChar32*, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">unistr.h</td><td class="proto">static UnicodeString UnicodeString::fromUTF8(const StringPiece&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">unistr.h</td><td class="proto">void UnicodeString::toUTF8(ByteSink&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uset.h</td><td class="proto">USet* uset_openEmpty()</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uset.h</td><td class="proto">void uset_closeOver(USet*, int32_t)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uset.h</td><td class="proto">void uset_removeAllStrings(USet*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">USpoofChecker* uspoof_clone(const USpoofChecker*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">USpoofChecker* uspoof_open(UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">USpoofChecker* uspoof_openFromSerialized(const void*, int32_t, int32_t*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">USpoofChecker* uspoof_openFromSource(const char*, int32_t, const char*, int32_t, int32_t*, UParseError*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">const USet* uspoof_getAllowedChars(const USpoofChecker*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">const char* uspoof_getAllowedLocales(USpoofChecker*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_areConfusable(const USpoofChecker*, const UChar*, int32_t, const UChar*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_areConfusableUTF8(const USpoofChecker*, const char*, int32_t, const char*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_check(const USpoofChecker*, const UChar*, int32_t, int32_t*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_checkUTF8(const USpoofChecker*, const char*, int32_t, int32_t*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_getChecks(const USpoofChecker*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_getSkeleton(const USpoofChecker*, uint32_t, const UChar*, int32_t, UChar*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_getSkeletonUTF8(const USpoofChecker*, uint32_t, const char*, int32_t, char*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">int32_t uspoof_serialize(USpoofChecker*, void*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">void uspoof_close(USpoofChecker*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">void uspoof_setAllowedChars(USpoofChecker*, const USet*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uspoof.h</td><td class="proto">void uspoof_setAllowedLocales(USpoofChecker*, const char*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uspoof.h</td><td class="proto">void uspoof_setChecks(USpoofChecker*, int32_t, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">usprep.h</td><td class="proto">UStringPrepProfile* usprep_openByType(UStringPrepProfileType, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ustring.h</td><td class="proto">UChar* u_strFromUTF32WithSub(UChar*, int32_t, int32_t*, const UChar32*, int32_t, UChar32, int32_t*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ustring.h</td><td class="proto">UChar32* u_strToUTF32WithSub(UChar32*, int32_t, int32_t*, const UChar*, int32_t, UChar32, int32_t*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uversion.h</td><td class="proto">void u_versionFromUString(UVersionInfo, const UChar*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft&raquo;Stable<br>4.2</td>
+</tr>
+</table>
+<P></P>
+<a href="#_top">(jump back to top)</a>
+<hr>
+<a name="added">
+<h2>Added in 4.4</h2>
+</a>
+<table BORDER="1" class="genTable">
+<THEAD>
+<tr>
+<th>File</th><th>API</th><th>4.2.1</th><th>4.4</th>
+</tr>
+</THEAD>
+<tr class="row1">
+<td class="file">calendar.h</td><td class="proto">UBool Calendar::isWeekend()const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">calendar.h</td><td class="proto">UBool Calendar::isWeekend(UDate, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">calendar.h</td><td class="proto">UCalendarWeekdayType Calendar::getDayOfWeekType(UCalendarDaysOfWeek, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">calendar.h</td><td class="proto">int32_t Calendar::getWeekendTransition(UCalendarDaysOfWeek, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">datefmt.h</td><td class="proto">UnicodeString&amp; DateFormat::format(Calendar&amp;, UnicodeString&amp;, FieldPositionIterator*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">datefmt.h</td><td class="proto">UnicodeString&amp; DateFormat::format(UDate, UnicodeString&amp;, FieldPositionIterator*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">datefmt.h</td><td class="proto">UnicodeString&amp; DateFormat::format(const Formattable&amp;, UnicodeString&amp;, FieldPositionIterator*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">decimfmt.h</td><td class="proto">UnicodeString&amp; DecimalFormat::format(const StringPiece&amp;, UnicodeString&amp;, FieldPositionIterator*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">decimfmt.h</td><td class="proto">UnicodeString&amp; DecimalFormat::format(double, UnicodeString&amp;, FieldPositionIterator*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">decimfmt.h</td><td class="proto">UnicodeString&amp; DecimalFormat::format(int32_t, UnicodeString&amp;, FieldPositionIterator*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">decimfmt.h</td><td class="proto">UnicodeString&amp; DecimalFormat::format(int64_t, UnicodeString&amp;, FieldPositionIterator*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">dtptngen.h</td><td class="proto">UnicodeString DateTimePatternGenerator::getBestPattern(const UnicodeString&amp;, UDateTimePatternMatchOptions, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">dtptngen.h</td><td class="proto">UnicodeString DateTimePatternGenerator::replaceFieldTypes(const UnicodeString&amp;, const UnicodeString&amp;, UDateTimePatternMatchOptions, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">errorcode.h</td><td class="proto">const char* ErrorCode::errorName() const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">errorcode.h</td><td class="proto">void ErrorCode::assertSuccess() const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">fmtable.h</td><td class="proto">Formattable::Formattable(const StringPiece&amp;, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">fmtable.h</td><td class="proto">const StringPiece&amp; Formattable::getDecimalNumber() const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">fmtable.h</td><td class="proto">void Formattable::setDecimalNumber(const StringPiece&amp;, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">format.h</td><td class="proto">UnicodeString&amp; Format::format(const Formattable&amp;, UnicodeString&amp;, FieldPositionIterator&amp;, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">fpositer.h</td><td class="proto">FieldPositionIterator::FieldPositionIterator()</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">fpositer.h</td><td class="proto">FieldPositionIterator::FieldPositionIterator(const FieldPositionIterator&amp;)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">fpositer.h</td><td class="proto">FieldPositionIterator::~FieldPositionIterator()</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">fpositer.h</td><td class="proto">UBool FieldPositionIterator::next(FieldPosition&amp;)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">fpositer.h</td><td class="proto">UBool FieldPositionIterator::operator!=(const FieldPositionIterator&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">fpositer.h</td><td class="proto">UBool FieldPositionIterator::operator==(const FieldPositionIterator&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">fpositer.h</td><td class="proto">UClassID FieldPositionIterator::getDynamicClassID() const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">fpositer.h</td><td class="proto">static UClassID FieldPositionIterator::getStaticClassID()</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">icudataver.h</td><td class="proto">#define U_ICU_DATA_KEY</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">icudataver.h</td><td class="proto">#define U_ICU_STD_BUNDLE</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">icudataver.h</td><td class="proto">#define U_ICU_VERSION_BUNDLE</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">icudataver.h</td><td class="proto">UBool u_isDataOlder(UVersionInfo, UBool*, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">icudataver.h</td><td class="proto">void u_getDataVersion(UVersionInfo, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">icuplug.h</td><td class="proto">#define UPLUG_NAME_MAX</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">icuplug.h</td><td class="proto">#define UPLUG_TOKEN</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">icuplug.h</td><td class="proto">UErrorCode uplug_getPlugLoadStatus(UPlugData*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">icuplug.h</td><td class="proto">UPlugData* uplug_loadPlugFromEntrypoint(UPlugEntrypoint*, const char*, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">icuplug.h</td><td class="proto">UPlugData* uplug_loadPlugFromLibrary(const char*, const char*, const char*, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">icuplug.h</td><td class="proto">UPlugData* uplug_nextPlug(UPlugData*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">icuplug.h</td><td class="proto">UPlugLevel uplug_getCurrentLevel()</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">icuplug.h</td><td class="proto">UPlugLevel uplug_getPlugLevel(UPlugData*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">icuplug.h</td><td class="proto">const char* uplug_getConfiguration(UPlugData*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">icuplug.h</td><td class="proto">const char* uplug_getLibraryName(UPlugData*, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">icuplug.h</td><td class="proto">const char* uplug_getPlugName(UPlugData*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">icuplug.h</td><td class="proto">const char* uplug_getSymbolName(UPlugData*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">icuplug.h</td><td class="proto">void uplug_removePlug(UPlugData*, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">icuplug.h</td><td class="proto">void uplug_setContext(UPlugData*, void*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">icuplug.h</td><td class="proto">void uplug_setPlugLevel(UPlugData*, UPlugLevel)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">icuplug.h</td><td class="proto">void uplug_setPlugName(UPlugData*, const char*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">icuplug.h</td><td class="proto">void uplug_setPlugNoUnload(UPlugData*, UBool)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">icuplug.h</td><td class="proto">void* uplug_getContext(UPlugData*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">icuplug.h</td><td class="proto">void* uplug_getLibrary(UPlugData*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Technology Preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">locdspnm.h</td><td class="proto">LocaleDisplayNames::~LocaleDisplayNames()</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">locdspnm.h</td><td class="proto">UDialectHandling LocaleDisplayNames::getDialectHandling() const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">locdspnm.h</td><td class="proto">UnicodeString&amp; LocaleDisplayNames::keyDisplayName(const char*, UnicodeString&amp;) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">locdspnm.h</td><td class="proto">UnicodeString&amp; LocaleDisplayNames::keyValueDisplayName(const char*, const char*, UnicodeString&amp;) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">locdspnm.h</td><td class="proto">UnicodeString&amp; LocaleDisplayNames::languageDisplayName(const char*, UnicodeString&amp;) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">locdspnm.h</td><td class="proto">UnicodeString&amp; LocaleDisplayNames::localeDisplayName(const Locale&amp;, UnicodeString&amp;) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">locdspnm.h</td><td class="proto">UnicodeString&amp; LocaleDisplayNames::localeDisplayName(const char*, UnicodeString&amp;) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">locdspnm.h</td><td class="proto">UnicodeString&amp; LocaleDisplayNames::regionDisplayName(const char*, UnicodeString&amp;) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">locdspnm.h</td><td class="proto">UnicodeString&amp; LocaleDisplayNames::scriptDisplayName(UScriptCode, UnicodeString&amp;) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">locdspnm.h</td><td class="proto">UnicodeString&amp; LocaleDisplayNames::scriptDisplayName(const char*, UnicodeString&amp;) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">locdspnm.h</td><td class="proto">UnicodeString&amp; LocaleDisplayNames::variantDisplayName(const char*, UnicodeString&amp;) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">locdspnm.h</td><td class="proto">const Locale&amp; LocaleDisplayNames::getLocale() const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">locdspnm.h</td><td class="proto">static LocaleDisplayNames* LocaleDisplayNames::createInstance(const Locale&amp;)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">locdspnm.h</td><td class="proto">static LocaleDisplayNames* LocaleDisplayNames::createInstance(const Locale&amp;, UDialectHandling)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">locid.h</td><td class="proto">static const Locale&amp; Locale::getRoot()</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">locid.h</td><td class="proto">void Locale::setKeywordValue(const char*, const char*, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">normalizer2.h</td><td class="proto">FilteredNormalizer2::FilteredNormalizer2(const Normalizer2&amp;, const UnicodeSet&amp;)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">normalizer2.h</td><td class="proto">UBool FilteredNormalizer2::hasBoundaryAfter(UChar32) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">normalizer2.h</td><td class="proto">UBool FilteredNormalizer2::hasBoundaryBefore(UChar32) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">normalizer2.h</td><td class="proto">UBool FilteredNormalizer2::isInert(UChar32) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">normalizer2.h</td><td class="proto">UBool FilteredNormalizer2::isNormalized(const UnicodeString&amp;, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">normalizer2.h</td><td class="proto">UBool Normalizer2::hasBoundaryAfter(UChar32) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">normalizer2.h</td><td class="proto">UBool Normalizer2::hasBoundaryBefore(UChar32) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">normalizer2.h</td><td class="proto">UBool Normalizer2::isInert(UChar32) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">normalizer2.h</td><td class="proto">UBool Normalizer2::isNormalized(const UnicodeString&amp;, UErrorCode&amp;) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">normalizer2.h</td><td class="proto">UClassID FilteredNormalizer2::getDynamicClassID() const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">normalizer2.h</td><td class="proto">UClassID Normalizer2::getDynamicClassID() const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">normalizer2.h</td><td class="proto">UNormalizationCheckResult FilteredNormalizer2::quickCheck(const UnicodeString&amp;, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">normalizer2.h</td><td class="proto">UNormalizationCheckResult Normalizer2::quickCheck(const UnicodeString&amp;, UErrorCode&amp;) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">normalizer2.h</td><td class="proto">UnicodeString Normalizer2::normalize(const UnicodeString&amp;, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">normalizer2.h</td><td class="proto">UnicodeString&amp; FilteredNormalizer2::append(UnicodeString&amp;, const UnicodeString&amp;, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">normalizer2.h</td><td class="proto">UnicodeString&amp; FilteredNormalizer2::normalize(const UnicodeString&amp;, UnicodeString&amp;, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">normalizer2.h</td><td class="proto">UnicodeString&amp; FilteredNormalizer2::normalizeSecondAndAppend(UnicodeString&amp;, const UnicodeString&amp;, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">normalizer2.h</td><td class="proto">UnicodeString&amp; Normalizer2::append(UnicodeString&amp;, const UnicodeString&amp;, UErrorCode&amp;) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">normalizer2.h</td><td class="proto">UnicodeString&amp; Normalizer2::normalize(const UnicodeString&amp;, UnicodeString&amp;, UErrorCode&amp;) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">normalizer2.h</td><td class="proto">UnicodeString&amp; Normalizer2::normalizeSecondAndAppend(UnicodeString&amp;, const UnicodeString&amp;, UErrorCode&amp;) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">normalizer2.h</td><td class="proto">int32_t FilteredNormalizer2::spanQuickCheckYes(const UnicodeString&amp;, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">normalizer2.h</td><td class="proto">int32_t Normalizer2::spanQuickCheckYes(const UnicodeString&amp;, UErrorCode&amp;) const =0</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">normalizer2.h</td><td class="proto">static UClassID FilteredNormalizer2::getStaticClassID()</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">normalizer2.h</td><td class="proto">static UClassID Normalizer2::getStaticClassID()</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">normalizer2.h</td><td class="proto">static const Normalizer2* Normalizer2::getInstance(const char*, const char*, UNormalization2Mode, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">numfmt.h</td><td class="proto">UnicodeString&amp; NumberFormat::format(const Formattable&amp;, UnicodeString&amp;, FieldPositionIterator*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">numfmt.h</td><td class="proto">UnicodeString&amp; NumberFormat::format(const StringPiece&amp;, UnicodeString&amp;, FieldPositionIterator*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">numfmt.h</td><td class="proto">UnicodeString&amp; NumberFormat::format(double, UnicodeString&amp;, FieldPositionIterator*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">numfmt.h</td><td class="proto">UnicodeString&amp; NumberFormat::format(int32_t, UnicodeString&amp;, FieldPositionIterator*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">numfmt.h</td><td class="proto">UnicodeString&amp; NumberFormat::format(int64_t, UnicodeString&amp;, FieldPositionIterator*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ParagraphLayout.h</td><td class="proto">le_bool ParagraphLayout::isDone() const</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">platform.h</td><td class="proto">#define UCLN_NO_AUTO_CLEANUP</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">platform.h</td><td class="proto">#define U_CHECK_DYLOAD</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">platform.h</td><td class="proto">#define U_ENABLE_DYLOAD</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">platform.h</td><td class="proto">#define U_GNUC_UTF16_STRING</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">platform.h</td><td class="proto">#define U_HAVE_GCC_ATOMICS</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">regex.h</td><td class="proto">RegexMatcher&amp; RegexMatcher::appendReplacement(UText*, UText*, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">regex.h</td><td class="proto">RegexMatcher&amp; RegexMatcher::reset(UText*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">regex.h</td><td class="proto">RegexMatcher* RegexPattern::matcher(UText*, PatternIsUTextFlag, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">regex.h</td><td class="proto">RegexMatcher::RegexMatcher(UText*, UText*, uint32_t, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">regex.h</td><td class="proto">RegexMatcher::RegexMatcher(UText*, uint32_t, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">regex.h</td><td class="proto">UText* RegexMatcher::appendTail(UText*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">regex.h</td><td class="proto">UText* RegexMatcher::getInput(UText*) const</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">regex.h</td><td class="proto">UText* RegexMatcher::group(UText*, MatcherDestIsUTextFlag, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">regex.h</td><td class="proto">UText* RegexMatcher::group(int32_t, UText*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">regex.h</td><td class="proto">UText* RegexMatcher::inputText() const</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">regex.h</td><td class="proto">UText* RegexMatcher::replaceAll(UText*, UText*, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">regex.h</td><td class="proto">UText* RegexMatcher::replaceFirst(UText*, UText*, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">regex.h</td><td class="proto">UText* RegexPattern::patternText() const</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">regex.h</td><td class="proto">int32_t RegexMatcher::split(UText*, UText*dest[], int32_t, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">regex.h</td><td class="proto">int32_t RegexPattern::split(UText*, UText*dest[], int32_t, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">regex.h</td><td class="proto">static RegexPattern* RegexPattern::compile(UText*, UParseError&amp;, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">regex.h</td><td class="proto">static RegexPattern* RegexPattern::compile(UText*, uint32_t, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">regex.h</td><td class="proto">static RegexPattern* RegexPattern::compile(UText*, uint32_t, UParseError&amp;, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">regex.h</td><td class="proto">static UBool RegexPattern::matches(UText*, UText*, UParseError&amp;, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">selfmt.h</td><td class="proto">Format* SelectFormat::clone()const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">selfmt.h</td><td class="proto">SelectFormat&amp; SelectFormat::operator=(const SelectFormat&amp;)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">selfmt.h</td><td class="proto">SelectFormat::SelectFormat(const SelectFormat&amp;)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">selfmt.h</td><td class="proto">SelectFormat::SelectFormat(const UnicodeString&amp;, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">selfmt.h</td><td class="proto">SelectFormat::~SelectFormat()</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">selfmt.h</td><td class="proto">UBool SelectFormat::operator!=(const Format&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">selfmt.h</td><td class="proto">UBool SelectFormat::operator==(const Format&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">selfmt.h</td><td class="proto">UClassID SelectFormat::getDynamicClassID() const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">selfmt.h</td><td class="proto">UnicodeString&amp; SelectFormat::format(const Formattable&amp;, UnicodeString&amp;, FieldPosition&amp;, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">selfmt.h</td><td class="proto">UnicodeString&amp; SelectFormat::format(const UnicodeString&amp;, UnicodeString&amp;, FieldPosition&amp;, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">selfmt.h</td><td class="proto">UnicodeString&amp; SelectFormat::toPattern(UnicodeString&amp;)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">selfmt.h</td><td class="proto">static UClassID SelectFormat::getStaticClassID()</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">selfmt.h</td><td class="proto">void SelectFormat::applyPattern(const UnicodeString&amp;, UErrorCode&amp;)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">selfmt.h</td><td class="proto">void SelectFormat::parseObject(const UnicodeString&amp;, Formattable&amp;, ParsePosition&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">smpdtfmt.h</td><td class="proto">UnicodeString&amp; SimpleDateFormat::format(Calendar&amp;, UnicodeString&amp;, FieldPositionIterator*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">smpdtfmt.h</td><td class="proto">UnicodeString&amp; SimpleDateFormat::format(UDate, UnicodeString&amp;, FieldPositionIterator*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">smpdtfmt.h</td><td class="proto">UnicodeString&amp; SimpleDateFormat::format(const Formattable&amp;, UnicodeString&amp;, FieldPositionIterator*, UErrorCode&amp;) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ucal.h</td><td class="proto">UBool ucal_isWeekend(const UCalendar*, UDate, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ucal.h</td><td class="proto">UCalendarWeekdayType ucal_getDayOfWeekType(const UCalendar*, UCalendarDaysOfWeek, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ucal.h</td><td class="proto">int32_t ucal_getWeekendTransition(const UCalendar*, UCalendarDaysOfWeek, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">udat.h</td><td class="proto">UCalendarDateFields udat_toCalendarDateField(UDateFormatField)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">udatpg.h</td><td class="proto">int32_t udatpg_getBestPatternWithOptions(UDateTimePatternGenerator*, const UChar*, int32_t, UDateTimePatternMatchOptions, UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">udatpg.h</td><td class="proto">int32_t udatpg_replaceFieldTypesWithOptions(UDateTimePatternGenerator*, const UChar*, int32_t, const UChar*, int32_t, UDateTimePatternMatchOptions, UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">uldnames.h</td><td class="proto">UDialectHandling uldn_getDialectHandling(const ULocaleDisplayNames*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">uldnames.h</td><td class="proto">ULocaleDisplayNames* uldn_open(const char*, UDialectHandling, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">uldnames.h</td><td class="proto">const char* uldn_getLocale(const ULocaleDisplayNames*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">uldnames.h</td><td class="proto">int32_t uldn_keyDisplayName(const ULocaleDisplayNames*, const char*, UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">uldnames.h</td><td class="proto">int32_t uldn_keyValueDisplayName(const ULocaleDisplayNames*, const char*, const char*, UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">uldnames.h</td><td class="proto">int32_t uldn_languageDisplayName(const ULocaleDisplayNames*, const char*, UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">uldnames.h</td><td class="proto">int32_t uldn_localeDisplayName(const ULocaleDisplayNames*, const char*, UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">uldnames.h</td><td class="proto">int32_t uldn_regionDisplayName(const ULocaleDisplayNames*, const char*, UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">uldnames.h</td><td class="proto">int32_t uldn_scriptCodeDisplayName(const ULocaleDisplayNames*, UScriptCode, UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">uldnames.h</td><td class="proto">int32_t uldn_scriptDisplayName(const ULocaleDisplayNames*, const char*, UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">uldnames.h</td><td class="proto">int32_t uldn_variantDisplayName(const ULocaleDisplayNames*, const char*, UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">uldnames.h</td><td class="proto">void uldn_close(ULocaleDisplayNames*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">uniset.h</td><td class="proto">int32_t UnicodeSet::span(const UnicodeString&amp;, int32_t, USetSpanCondition) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">uniset.h</td><td class="proto">int32_t UnicodeSet::spanBack(const UnicodeString&amp;, int32_t, USetSpanCondition) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">unistr.h</td><td class="proto">UnicodeString UnicodeString::tempSubString(int32_t start=, int32_t length=) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">unistr.h</td><td class="proto">UnicodeString UnicodeString::tempSubStringBetween(int32_t, int32_t limit=) const</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">unistr.h</td><td class="proto">UnicodeString&amp; UnicodeString::retainBetween(int32_t, int32_t limit=)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">unorm2.h</td><td class="proto">UBool unorm2_hasBoundaryAfter(const UNormalizer2*, UChar32)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">unorm2.h</td><td class="proto">UBool unorm2_hasBoundaryBefore(const UNormalizer2*, UChar32)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">unorm2.h</td><td class="proto">UBool unorm2_isInert(const UNormalizer2*, UChar32)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">unorm2.h</td><td class="proto">UBool unorm2_isNormalized(const UNormalizer2*, const UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">unorm2.h</td><td class="proto">UNormalizationCheckResult unorm2_quickCheck(const UNormalizer2*, const UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">unorm2.h</td><td class="proto">UNormalizer2* unorm2_openFiltered(const UNormalizer2*, const USet*, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">unorm2.h</td><td class="proto">const UNormalizer2* unorm2_getInstance(const char*, const char*, UNormalization2Mode, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">unorm2.h</td><td class="proto">int32_t unorm2_append(const UNormalizer2*, UChar*, int32_t, int32_t, const UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">unorm2.h</td><td class="proto">int32_t unorm2_normalize(const UNormalizer2*, const UChar*, int32_t, UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">unorm2.h</td><td class="proto">int32_t unorm2_normalizeSecondAndAppend(const UNormalizer2*, UChar*, int32_t, int32_t, const UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">unorm2.h</td><td class="proto">int32_t unorm2_spanQuickCheckYes(const UNormalizer2*, const UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">unorm2.h</td><td class="proto">void unorm2_close(UNormalizer2*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">unum.h</td><td class="proto">int32_t unum_formatDecimal(const UNumberFormat*, const char*, int32_t, UChar*, int32_t, UFieldPosition*, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">unum.h</td><td class="proto">int32_t unum_parseDecimal(const UNumberFormat*, const UChar*, int32_t, int32_t*, char*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">uregex.h</td><td class="proto">URegularExpression* uregex_openUText(UText*, uint32_t, UParseError*, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">uregex.h</td><td class="proto">UText* uregex_appendTailUText(URegularExpression*, UText*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">uregex.h</td><td class="proto">UText* uregex_getUText(URegularExpression*, UText*, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">uregex.h</td><td class="proto">UText* uregex_groupUText(URegularExpression*, int32_t, UText*, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">uregex.h</td><td class="proto">UText* uregex_patternUText(const URegularExpression*, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">uregex.h</td><td class="proto">UText* uregex_replaceAllUText(URegularExpression*, UText*, UText*, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">uregex.h</td><td class="proto">UText* uregex_replaceFirstUText(URegularExpression*, UText*, UText*, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">uregex.h</td><td class="proto">int32_t uregex_splitUText(URegularExpression*, UText*destFields[], int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">uregex.h</td><td class="proto">void uregex_appendReplacementUText(URegularExpression*, UText*, UText*, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">uregex.h</td><td class="proto">void uregex_setUText(URegularExpression*, UText*, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ustdio.h</td><td class="proto">UFILE* u_fadopt(FILE*, const char*, const char*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ustring.h</td><td class="proto">UChar* u_strFromJavaModifiedUTF8WithSub(UChar*, int32_t, int32_t*, const char*, int32_t, UChar32, int32_t*, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ustring.h</td><td class="proto">char* u_strToJavaModifiedUTF8(char*, int32_t, int32_t*, const UChar*, int32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.4</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">utext.h</td><td class="proto">#define UTEXT_CURRENT32</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">utext.h</td><td class="proto">int32_t utext_caseCompare(UText*, int32_t, UText*, int32_t, uint32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">utext.h</td><td class="proto">int32_t utext_caseCompareNativeLimit(UText*, int64_t, UText*, int64_t, uint32_t, UErrorCode*)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">utext.h</td><td class="proto">int32_t utext_compare(UText*, int32_t, UText*, int32_t)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">utext.h</td><td class="proto">int32_t utext_compareNativeLimit(UText*, int64_t, UText*, int64_t)</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 technology preview</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">utypes.h</td><td class="proto">#define U_SHOW_CPLUSPLUS_API</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">utypes.h</td><td class="proto">#define U_USE_USRDATA</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">utypes.h</td><td class="proto">#define U_USRDATA_NAME</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>.</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">uvernum.h</td><td class="proto">#define U_ICU_DATA_VERSION</td><td class="">None<br>
+</td><td>Internal<br>
+<span class=""><span>4.4 Internal Use Only</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">uvernum.h</td><td class="proto">#define U_ICU_ENTRY_POINT_RENAME</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span>
+<br>
+<b class="bigwarn" title="A draft API has the wrong version.">(should be 4.4)</b></span></td>
+</tr>
+</table>
+<P></P>
+<a href="#_top">(jump back to top)</a>
+<hr>
+<a name="other">
+<h2>Other existing drafts in 4.4</h2>
+</a>
+<div class="other">
+<table BORDER="1" class="genTable">
+<THEAD>
+<tr>
+<th>File</th><th>API</th><th>4.2.1</th><th>4.4</th>
+</tr>
+</THEAD>
+<tr class="row1">
+<td class="file">dcfmtsym.h</td><td class="proto">const UnicodeString&amp; DecimalFormatSymbols::getPatternForCurrencySpacing(ECurrencySpacing, UBool, UErrorCode&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">dcfmtsym.h</td><td class="proto">void DecimalFormatSymbols::setPatternForCurrencySpacing(ECurrencySpacing, UBool, const UnicodeString&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numfmt.h</td><td class="proto">static NumberFormat* NumberFormat::createInstance(const Locale&amp;, EStyles, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">platform.h</td><td class="proto">#define U_HAVE_STD_STRING</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">std_string.h</td><td class="proto">#define U_STD_NSQ</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">std_string.h</td><td class="proto">#define U_STD_NS_USE</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">std_string.h</td><td class="proto">#define U_STD_NS</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">TimeUnitFormat::TimeUnitFormat(const Locale&amp;, EStyle, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uloc.h</td><td class="proto">int32_t uloc_forLanguageTag(const char*, char*, int32_t, int32_t*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uloc.h</td><td class="proto">int32_t uloc_toLanguageTag(const char*, char*, int32_t, UBool, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define SHAPE_TAIL_NEW_UNICODE</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define SHAPE_TAIL_TYPE_MASK</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_AUTO</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_BEGIN</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_END</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_MASK</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_NEAR</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_RESIZE</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_SEEN_MASK</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_SEEN_TWOCELL_NEAR</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_SPACES_RELATIVE_TO_TEXT_BEGIN_END</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_SPACES_RELATIVE_TO_TEXT_MASK</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TASHKEEL_BEGIN</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TASHKEEL_END</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TASHKEEL_MASK</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TASHKEEL_REPLACE_BY_TATWEEL</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TASHKEEL_RESIZE</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TEXT_DIRECTION_VISUAL_RTL</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_YEHHAMZA_MASK</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_YEHHAMZA_TWOCELL_NEAR</td><td class="">
+<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+<tr class="row1">
+<td class="file">utf.h</td><td class="proto">#define U_IS_SURROGATE_TRAIL</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">utf16.h</td><td class="proto">#define U16_IS_SURROGATE_TRAIL</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">utypes.h</td><td class="proto">#define U_CHARSET_IS_UTF8</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uvernum.h</td><td class="proto">#define U_ICU_ENTRY_POINT_RENAME</td><td class="">None<br>
+</td><td>Draft<br>
+<span class=""><span>4.2</span></span></td>
+</tr>
+</table>
+</div>
+<P></P>
+<a href="#_top">(jump back to top)</a>
+<hr>
+<p>
+<i><font size="-1">Contents generated by StableAPI (r27279:27490M) tool on Wed Feb 10 16:49:50 PST 2010<br>Copyright (C) 2010, International Business Machines Corporation, All Rights Reserved.</font></i>
+</p>
+</body>
+</html>
diff --git a/icu/APIChangeReport441.html b/icu/APIChangeReport441.html
new file mode 100644
index 0000000..0fc5194
--- /dev/null
+++ b/icu/APIChangeReport441.html
@@ -0,0 +1,357 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+	 Copyright (C)  2010, International Business Machines Corporation, All Rights Reserved. 
+	--><html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>ICU4C API Comparison: release 4.4 with 4.4.1 (r27971, maint-4-4)</title>
+<link type="text/css" href="icu4c.css" rel="stylesheet">
+</head>
+<body>
+<a name="_top"></a>
+<h1>ICU4C API Comparison: release 4.4 with 4.4.1 (r27971, maint-4-4)</h1>
+
+<i>Note: This change report compares the trivial changes between 4.4 and 4.4.1.  For the changes betweeen the 4.4 stream and the previous major release, see <a href="APIChangeReport.html">APIChangeReport.html</a></i>
+<ul>
+<li>
+<a href="#removed">Removed from 4.4</a>
+</li>
+<li>
+<a href="#deprecated">Deprecated or Obsoleted in 4.4.1</a>
+</li>
+<li>
+<a href="#changed">Changed in  4.4</a>
+</li>
+<li>
+<a href="#promoted">Promoted to stable in 4.4.1</a>
+</li>
+<li>
+<a href="#added">Added in 4.4.1</a>
+</li>
+<li>
+<a href="#other">Other existing drafts in 4.4.1</a>
+</li>
+</ul>
+<hr>
+<a name="removed">
+<h2>Removed from 4.4</h2>
+</a>
+<table BORDER="1" class="genTable">
+<THEAD>
+<tr>
+<th>File</th><th>API</th><th>4.4</th><th>4.4.1</th></th>
+</tr>
+</THEAD>
+</table>
+<P></P>
+<a href="#_top">(jump back to top)</a>
+<hr>
+<a name="deprecated">
+<h2>Deprecated or Obsoleted in 4.4.1</h2>
+</a>
+<table BORDER="1" class="genTable">
+<THEAD>
+<tr>
+<th>File</th><th>API</th><th>4.4</th><th>4.4.1</th></th>
+</tr>
+</THEAD>
+</table>
+<P></P>
+<a href="#_top">(jump back to top)</a>
+<hr>
+<a name="changed">
+<h2>Changed in  4.4.1 (old, new)</h2>
+</a>
+<table BORDER="1" class="genTable">
+<THEAD>
+<tr>
+<th>File</th><th>API</th><th>4.4</th><th>4.4.1</th></th>
+</tr>
+</THEAD>
+</table>
+<P></P>
+<a href="#_top">(jump back to top)</a>
+<hr>
+<a name="promoted">
+<h2>Promoted to stable in 4.4.1</h2>
+</a>
+<table BORDER="1" class="genTable">
+<THEAD>
+<tr>
+<th>File</th><th>API</th><th>4.4</th><th>4.4.1</th></th>
+</tr>
+</THEAD>
+</table>
+<P></P>
+<a href="#_top">(jump back to top)</a>
+<hr>
+<a name="added">
+<h2>Added in 4.4.1</h2>
+</a>
+<table BORDER="1" class="genTable">
+<THEAD>
+<tr>
+<th>File</th><th>API</th><th>4.4</th><th>4.4.1</th></th>
+</tr>
+</THEAD>
+</table>
+<P></P>
+<a href="#_top">(jump back to top)</a>
+<hr>
+<a name="other">
+<h2>Other existing drafts in 4.4.1</h2>
+</a>
+<div class="other">
+<table BORDER="1" class="genTable">
+<THEAD>
+<tr>
+<th>File</th><th>API</th><th>4.4</th><th>4.4.1</th></th>
+</tr>
+</THEAD>
+<tr class="row1">
+<td class="file">dcfmtsym.h</td><td class="proto">const UnicodeString&amp; DecimalFormatSymbols::getPatternForCurrencySpacing(ECurrencySpacing, UBool, UErrorCode&amp;) const</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">dcfmtsym.h</td><td class="proto">void DecimalFormatSymbols::setPatternForCurrencySpacing(ECurrencySpacing, UBool, const UnicodeString&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">numfmt.h</td><td class="proto">static NumberFormat* NumberFormat::createInstance(const Locale&amp;, EStyles, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">platform.h</td><td class="proto">#define U_HAVE_STD_STRING</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">std_string.h</td><td class="proto">#define U_STD_NSQ</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">std_string.h</td><td class="proto">#define U_STD_NS_USE</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">std_string.h</td><td class="proto">#define U_STD_NS</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">tmutfmt.h</td><td class="proto">TimeUnitFormat::TimeUnitFormat(const Locale&amp;, EStyle, UErrorCode&amp;)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">uloc.h</td><td class="proto">int32_t uloc_forLanguageTag(const char*, char*, int32_t, int32_t*, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uloc.h</td><td class="proto">int32_t uloc_toLanguageTag(const char*, char*, int32_t, UBool, UErrorCode*)</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define SHAPE_TAIL_NEW_UNICODE</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define SHAPE_TAIL_TYPE_MASK</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_AUTO</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_BEGIN</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_END</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_MASK</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_NEAR</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_LAMALEF_RESIZE</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_SEEN_MASK</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_SEEN_TWOCELL_NEAR</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_SPACES_RELATIVE_TO_TEXT_BEGIN_END</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_SPACES_RELATIVE_TO_TEXT_MASK</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TASHKEEL_BEGIN</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TASHKEEL_END</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TASHKEEL_MASK</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TASHKEEL_REPLACE_BY_TATWEEL</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TASHKEEL_RESIZE</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_TEXT_DIRECTION_VISUAL_RTL</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_YEHHAMZA_MASK</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">ushape.h</td><td class="proto">#define U_SHAPE_YEHHAMZA_TWOCELL_NEAR</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">utf.h</td><td class="proto">#define U_IS_SURROGATE_TRAIL</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">utf16.h</td><td class="proto">#define U16_IS_SURROGATE_TRAIL</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row1">
+<td class="file">utypes.h</td><td class="proto">#define U_CHARSET_IS_UTF8</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+<tr class="row0">
+<td class="file">uvernum.h</td><td class="proto">#define U_ICU_ENTRY_POINT_RENAME</td><td class="" colspan="
+       	            		2
+       	            	" align="
+       	            		center
+       	            	">Draft<br>4.2</td>
+</tr>
+</table>
+</div>
+<P></P>
+<a href="#_top">(jump back to top)</a>
+<hr>
+<p>
+<i><font size="-1">Contents generated by StableAPI (r27279:27490M) tool on Thu Apr 22 13:05:02 PDT 2010<br>Copyright (C) 2010, International Business Machines Corporation, All Rights Reserved.</font></i>
+</p>
+</body>
+</html>
diff --git a/icu/as_is/os390/unpax-icu.sh b/icu/as_is/os390/unpax-icu.sh
new file mode 100644
index 0000000..23a1ebc
--- /dev/null
+++ b/icu/as_is/os390/unpax-icu.sh
@@ -0,0 +1,102 @@
+#!/bin/sh
+# Copyright (C) 2001-2007, International Business Machines
+#   Corporation and others.  All Rights Reserved.
+#
+# Authors:
+# Ami Fixler
+# Steven R. Loomis
+# George Rhoten
+#
+# Shell script to unpax ICU and convert the files to an EBCDIC codepage.
+# After extracting to EBCDIC, binary files are re-extracted without the
+# EBCDIC conversion, thus restoring them to original codepage.
+#
+# Set the following variable to the list of binary file suffixes (extensions)
+
+#binary_suffixes='ico ICO bmp BMP jpg JPG gif GIF brk BRK'
+#ICU specific binary files
+binary_suffixes='brk BRK bin BIN res RES cnv CNV dat DAT icu ICU spp SPP xml XML'
+
+usage()
+{
+    echo "Enter archive filename as a parameter: $0 icu-archive.tar"
+}
+# first make sure we at least one arg and it's a file we can read
+if [ $# -eq 0 ]; then
+    usage
+    exit
+fi
+tar_file=$1
+if [ ! -r $tar_file ]; then
+    echo "$tar_file does not exist or cannot be read."
+    usage
+    exit
+fi
+
+echo ""
+echo "Extracting from $tar_file ..."
+echo ""
+# extract files while converting them to EBCDIC
+pax -rvf $tar_file -o to=IBM-1047,from=ISO8859-1 -o setfiletag
+
+echo ""
+echo "Determining binary files ..."
+echo ""
+
+# When building in ASCII mode, text files are converted as ASCII
+if [ "${ICU_ENABLE_ASCII_STRINGS}" -eq 1 ]; then
+    binary_suffixes="$binary_suffixes txt TXT ucm UCM"
+else
+	for file in `find ./icu \( -name \*.txt -print \) | sed -e 's/^\.\///'`; do
+		bom8=`head -c 3 $file|\
+			od -t x1|\
+			head -n 1|\
+			sed 's/  */ /g'|\
+			cut -f2-4 -d ' '|\
+			tr 'A-Z' 'a-z'`;
+		#Find a converted UTF-8 BOM
+		if [ "$bom8" = "57 8b ab" ]
+		then
+			binary_files="$binary_files $file";
+		fi
+	done
+fi
+
+for i in $(pax -f $tar_file 2>/dev/null)
+do
+	case $i in
+	*/) ;;		# then this entry is a directory
+	*.*)		# then this entry has a dot in the filename
+		for j in $binary_suffixes
+		do
+			# We substitute the suffix more than once
+			# to handle files like NormalizationTest-3.2.0.txt
+			suf=${i#*.*}
+			suf=${suf#*.*}
+			suf=${suf#*.*}
+			if [ "$suf" = "$j" ]
+			then
+				binary_files="$binary_files $i"
+				break
+			fi
+		done
+		;;
+	*) ;;		# then this entry does not have a dot in it
+    esac
+done
+
+# now see if a re-extract of binary files is necessary
+if [ ${#binary_files} -eq 0 ]; then
+    echo ""
+    echo "There are no binary files to restore."
+else
+    echo "Restoring binary files ..."
+    echo ""
+    rm $binary_files
+    pax -rvf $tar_file $binary_files
+    # Tag the files as binary for proper interaction with the _BPXK_AUTOCVT
+    # environment setting
+    chtag -b $binary_files
+fi
+echo ""
+echo "$0 has completed extracting ICU from $tar_file."
diff --git a/icu/as_is/os400/convertConfigure.sed b/icu/as_is/os400/convertConfigure.sed
new file mode 100644
index 0000000..6231958
--- /dev/null
+++ b/icu/as_is/os400/convertConfigure.sed
@@ -0,0 +1,32 @@
+# Copyright (C) 2006-2009, International Business Machines Corporation
+# and others.  All Rights Reserved.
+#
+# Use "test -x" instead of "test -f" most of the time.
+# due to how executables are created in a different file system.
+s/as_executable_p="test -f"/as_executable_p="test -x"/g
+s/test -f "$ac_file"/test -x "$ac_file"/g
+s/test -f $ac_dir\/install-sh/test -x $ac_dir\/install-sh/g
+s/test -f $ac_dir\/install.sh/test -x $ac_dir\/install.sh/g
+s/test -f $ac_dir\/shtool/test -x $ac_dir\/shtool/g
+# Use the more efficient del instead of rm command.
+s/rm[ ]*-r[ ]*-f/del -f/g
+s/rm[ ]*-f[ ]*-r/del -f/g
+s/rm[ ]*-rf/del -f/g
+s/rm[ ]*-fr/del -f/g
+s/rm[ ]*-f/del -f/g
+##don't clean up some awks for debugging
+#s/[ ]*del -f [^ ]*.awk/#&/
+# Borne shell isn't always available on i5/OS
+s/\/bin\/sh/\/usr\/bin\/qsh/g
+# no diff in qsh the equivalent is cmp
+s/ diff / cmp -s /g
+## srl
+# trouble w/ redirects.
+s% >&$3%%g
+s%^ac_cr=%# AWK reads ASCII, not EBCDIC\
+touch -C 819 $tmp/defines.awk $tmp/subs.awk $tmp/subs1.awk conf$$subs.awk\
+\
+&%
+##OBSOLETE
+#(REPLACED BY CPP in runConfigureICU) Use -c qpponly instead of -E to enable the preprocessor on the compiler
+#s/\$CC -E/\$CC -c -qpponly/g
diff --git a/icu/as_is/os400/unpax-icu.sh b/icu/as_is/os400/unpax-icu.sh
new file mode 100644
index 0000000..db31e02
--- /dev/null
+++ b/icu/as_is/os400/unpax-icu.sh
@@ -0,0 +1,195 @@
+#!/usr/bin/qsh
+#   Copyright (C) 2000-2009, International Business Machines
+#   Corporation and others.  All Rights Reserved.
+#
+# Authors:
+# Ami Fixler
+# Barry Novinger
+# Steven R. Loomis
+# George Rhoten
+# Jason Spieth
+#
+# Shell script to unpax ICU and convert the files to an EBCDIC codepage.
+# After extracting to EBCDIC, binary files are re-extracted without the
+# EBCDIC conversion, thus restoring them to original codepage.
+
+if [ -z "$QSH_VERSION" ];
+then
+	QSH=0
+    echo "QSH not detected (QSH_VERSION not set) - just testing."
+else
+	QSH=1
+	#echo "QSH version $QSH_VERSION"
+fi
+export QSH
+
+# Set the following variable to the list of binary file suffixes (extensions)
+
+
+#****************************************************************************
+#binary_suffixes='ico ICO bmp BMP jpg JPG gif GIF brk BRK'
+#ICU specific binary files
+#****************************************************************************
+binary_suffixes='brk BRK bin BIN res RES cnv CNV dat DAT icu ICU spp SPP xml XML'
+data_files='icu/source/data/brkitr/* icu/source/data/locales/* icu/source/data/coll/* icu/source/data/rbnf/* icu/source/data/mappings/* icu/source/data/misc/* icu/source/data/translit/* icu/source/data/unidata/* icu/source/test/testdata/*'
+
+#****************************************************************************
+# Function:     usage
+# Description:  Prints out text that describes how to call this script
+# Input:        None
+# Output:       None
+#****************************************************************************
+usage()
+{
+  echo "Enter archive filename as a parameter: $0 icu-archive.tar"
+}
+
+#****************************************************************************
+# first make sure we at least one arg and it's a file we can read
+#****************************************************************************
+
+# check for no arguments
+if [ $# -eq 0 ]; then
+  usage
+  exit
+fi
+
+# tar file is argument 1
+tar_file=$1
+
+# check that the file is valid
+if [ ! -r $tar_file ]; then
+  echo "$tar_file does not exist or cannot be read."
+  usage
+  exit
+fi
+
+#****************************************************************************
+# Determine which directories in the data_files list
+# are included in the provided archive
+#****************************************************************************
+echo "Finding data_files ..."
+for data_dir in $data_files
+do
+   if (pax -f $tar_file $data_dir >/dev/null 2>&1)
+   then
+       ebcdic_data="$ebcdic_data `echo $data_dir`";
+   fi
+done
+
+#****************************************************************************
+# Extract files.  We do this in two passes.  One pass for 819 files and a
+# second pass for 37 files
+#****************************************************************************
+echo ""
+echo "Extracting from $tar_file ..."
+echo ""
+
+# extract everything as iso-8859-1 except these directories
+pax -C 819 -rcvf $tar_file $ebcdic_data
+
+# extract files while converting them to EBCDIC
+echo ""
+echo "Extracting files which must be in ibm-37 ..."
+echo ""
+pax -C 37 -rvf $tar_file $ebcdic_data
+
+#****************************************************************************
+# For files we have restored as CCSID 37, check the BOM to see if they    
+# should be processed as 819.  Also handle files with special paths. Files
+# that match will be added to binary files lists.  The lists will in turn
+# be processed to restore files as 819.
+#****************************************************************************
+echo ""
+echo "Determining binary files by BOM ..."
+echo ""
+bin_count=0
+# Process BOMs
+for file in `find ./icu \( -name \*.txt -print \)`; do
+    bom8=`head -n 1 $file|\
+          od -t x1|\
+          head -n 1|\
+          sed 's/  */ /g'|\
+          cut -f2-4 -d ' '|\
+          tr 'A-Z' 'a-z'`;
+    #Find a converted UTF-8 BOM
+    if [ "$bom8" = "057 08b 0ab" -o "$bom8" = "57 8b ab" ]
+    then
+        file="`echo $file | cut -d / -f2-`"
+
+        if [ `echo $binary_files | wc -w` -lt 200 ]
+        then
+            bin_count=`expr $bin_count + 1`
+            binary_files="$binary_files $file";
+        else
+            echo "Restoring binary files by BOM ($bin_count)..."
+            rm $binary_files;
+            pax -C 819 -rvf $tar_file $binary_files;
+            echo "Determining binary files by BOM ($bin_count)..."
+            binary_files="$file";
+            bin_count=`expr $bin_count + 1`
+        fi
+    fi
+done
+
+# Process special paths
+for i in $(pax -f $tar_file 2>/dev/null)
+do
+  case $i in
+    */)
+#    then this entry is a directory
+     ;;
+    *.*)
+#    then this entry has a dot in the filename
+     for j in $binary_suffixes
+     do
+       suf=${i#*.*}
+       if [ "$suf" = "$j" ]
+       then
+
+         if [ `echo $binary_files | wc -w` -lt 200 ]
+         then
+            binary_files="$binary_files $i";
+            bin_count=`expr $bin_count + 1`
+         else
+            echo "Restoring binary files by special paths ($bin_count) ..."
+            rm $binary_files;
+            pax -C 819 -rvf $tar_file $binary_files;
+            echo "Determining binary files by special paths ($bin_count) ..."
+            binary_files="$i";
+            bin_count=`expr $bin_count + 1`
+         fi
+         break
+       fi
+     done
+     ;;
+    *)
+#    then this entry does not have a dot in it
+     ;;
+  esac
+done
+
+# now see if a re-extract of binary files is necessary
+if [ `echo $binary_files | wc -w` -gt 0 ]
+then
+  echo "Restoring binary files ($bin_count) ..."
+  rm $binary_files
+  pax -C 819 -rvf $tar_file $binary_files
+fi
+
+#****************************************************************************
+# Generate and run the configure script
+#****************************************************************************
+
+echo ""
+echo "Generating qsh compatible configure ..."
+echo ""
+
+sed -f icu/as_is/os400/convertConfigure.sed icu/source/configure > icu/source/configureTemp
+del -f icu/source/configure
+mv icu/source/configureTemp icu/source/configure
+chmod 755 icu/source/configure
+
+echo ""
+echo "$0 has completed extracting ICU from $tar_file - $bin_count binary files extracted."
+
diff --git a/icu/icu4c.css b/icu/icu4c.css
new file mode 100644
index 0000000..aacacb8
--- /dev/null
+++ b/icu/icu4c.css
@@ -0,0 +1,447 @@
+/*
+ * Default CSS style sheet for the ICU4C Open Source readme
+ * Copyright (C) 2005-2009, International Business Machines
+ * Corporation and others.  All Rights Reserved.
+ */
+
+/* Global styles */
+
+body,p,li,ol,ul,th,td {
+	font-size: 10pt;
+	font-family: "Arial", "Helvetica", sans-serif;
+}
+
+body {
+	margin: 1em;
+}
+
+body.draft {
+	background-image: url(images/draftbg.png);
+}
+
+.mainbody {
+	padding: 1em;
+}
+
+/*
+ * Customize the headers to have less space around them than usual
+ */
+
+h1 {
+	margin-bottom: .5em;
+	margin-top: .5em;
+	padding-bottom: .5em;
+	padding-top: .5em;
+	font-weight: 700;
+	font-size: 20pt;
+	font-family: Georgia, "Times New Roman", Times, serif;
+	border-width: 2px;
+	border-style: solid;
+	text-align: center;
+	width: 100%;
+	font-size: 200%;
+	font-weight: bold;
+}
+
+h2 {
+	border-top: 2px solid #22d;
+	border-left: 2px solid #22d;
+	margin-bottom: 0.5em;
+	padding-left: 4px;
+	margin-top: 12pt;
+	font-weight: 700;
+	font-size: 2em;
+	font-family: Georgia, "Times New Roman", Times, serif;
+	background-color: #eee;
+	page-break-before: always;
+}
+
+h2 a {
+	text-decoration: none;
+	color: black;
+}
+
+h2 a:hover {
+	color: blue;
+	text-decoration: underline;
+}
+
+h3 {
+	border-top: 1px solid gray;
+	color: #1e1c46;
+	margin-bottom: 0pt;
+	margin-top: 12pt;
+	padding-left: 0;
+	margin-left: 1em;
+	margin-top: 0.2em;
+	padding-bottom: 0.4em;
+	font-size: 1.5em;
+	font-family: Georgia, "Times New Roman", Times, serif;
+}
+
+h3 a {
+	text-decoration: none;
+	color: black;
+}
+
+h3 a:hover {
+	color: blue;
+	text-decoration: underline;
+}
+
+h4 {
+	margin-left: 1.5em;
+	margin-bottom: 0pt;
+	margin-top: 12pt;
+	font-size: 1.0em;
+	font-weight: bolder;
+	font-family: Georgia, "Times New Roman", Times, serif;
+}
+
+h4 a {
+	text-decoration: none;
+	color: black;
+}
+
+h4 a:hover {
+	color: blue;
+	text-decoration: underline;
+}
+
+h5, h6 {
+	margin-left: 1.8em;
+	margin-bottom: 0pt;
+	margin-top: 12pt;
+	padding-left: 0.75em;
+	font-size: x-small;
+	font-family: Georgia, "Times New Roman", Times, serif;
+}
+
+p,pre,table,ul,ol,dl {
+	margin-left: 2em;
+}
+
+/*
+ * Navigation sidebar on the left hand of most pages
+ */
+
+td.sidebar1 {
+	background-color: #99CCFF;
+	font-weight: 700;
+	margin-top: 0px;
+	margin-bottom: 0px;
+	padding-top: 1em;
+	padding-left: 0.2em;
+	white-space: nowrap;
+}
+
+td.sidebar2 {
+	background-color: #99CCFF;
+	margin-top: 0px;
+	margin-bottom: 0px;
+	margin-left: 0px;
+	padding-top: 1px;
+	padding-bottom: 1px;
+	padding-left: 1px;
+	padding-right: 0.5em;
+	white-space: nowrap;
+	text-decoration: none;
+	display: block;
+}
+
+td.sidebar2:hover {
+	background-color: #EEEEFF;
+	padding-top: 1px;
+	padding-bottom: 1px;
+	padding-left: 1px;
+	padding-right: 0.5em;
+}
+
+a.sidebar2 {
+	text-decoration: none;
+	display: block;
+	width: 100%;
+}
+
+a.sidebar2:link {
+	color: #000099;
+	display: block;
+}
+
+a.sidebar2:hover {
+	background-color: #EEEEFF;
+	display: block;
+}
+
+.underlinehover:hover {
+	background-color: #EEEEFF;
+	text-decoration: underline;
+}
+
+/* This is the faded header at the top */
+
+td.fadedtop {
+	background-color: #006699;
+	background-image: url(http://www.icu-project.org/images/gr100.gif);
+}
+
+/* Related site on the left */
+
+p.relatedsite {
+	color: White;
+	font-weight: 700;
+	font-size: 10pt;
+	margin-top: 1em;
+	margin-bottom: 0;
+	padding-left: 0.2em;
+	white-space: nowrap;
+}
+
+/* Related site on the left */
+
+p.sidebar3 {
+	margin-top: 0.75em;
+	margin-bottom: 0;
+	padding-left: 0.8em;
+}
+
+a.sidebar3 {
+	font-size: 0.9em;
+	text-decoration: none;
+}
+
+a.sidebar3:link {
+	text-decoration: none;
+	color: White;
+}
+
+a.sidebar3:hover {
+	text-decoration: underline;
+}
+
+/* FAQ */
+
+li.faq_contents {
+	font-weight: 500;
+}
+
+p.faq_q {
+	font-weight: 700;
+	margin-bottom: 0px;
+}
+
+p.faq_a {
+	margin-top: 0px;
+}
+
+/* News items */
+
+table.newsItem {
+	padding-left: 1em;
+	padding-right: 1em;
+	border-width: medium;
+}
+
+th.newsItem {
+	background-color: #666666;
+	color: White;
+}
+
+td.newsItem {
+	background-color: #CCCCCC;
+}
+
+td.release-line,th.release-line {
+	padding-left: 0.5em;
+	padding-right: 0.5em;
+	white-space: nowrap;
+	border: 1px;
+}
+
+.note {
+	font-style: italic;
+	font-size: small;
+	margin-left: 1em;
+}
+
+samp {
+	margin-left: 1em;
+	margin-right: 2em;
+	border-style: groove;
+	padding: 1em;
+	display: block;
+	background-color: #EEEEEE
+}
+
+table.rtable caption {
+	margin-left: 2px;
+	margin-right: 2px;
+	padding: 3px;
+	font-weight: bold;
+	background-color: #dee2ff;
+	text-align: left;
+}
+
+table.rtable tr th {
+	background-color: #dee2ff;
+	text-align: left;
+}
+
+table.rtable tr td {
+	background-color: #c0c0fd;
+	padding: 3px;
+}
+
+table.rtable tr.broken td {
+	background-color: #fbb;
+	border: 1px dashed gray;
+	padding: 3px;
+	font-weight: bold;
+}
+
+table.rtable tr.rarely td {
+	background-color: #efe9c2;
+	padding: 3px;
+	font-style: italic;
+}
+
+/*  APIChangeReport specific things */
+
+.row0 {
+	background-color: white;
+}
+
+.row1 {
+	background-color: #dfd;
+}
+
+.verchange {
+	color: red;
+	font-weight: bold;
+	font-size: large;
+}
+
+.stabchange {
+	color: red;
+	font-size: large;
+}
+
+.bigwarn {
+	color: red;
+	background-color: white;
+	font-size: x-large;
+	margin: 0.5 em;
+}
+
+table.genTable {
+	border-collapse: collapse;
+	border: 1px solid black;
+}
+
+/* 'everything inc version */
+
+table.gentable td {
+	border: 1px solid gray;
+	padding: 0.25em;
+	font-size: small;
+}
+
+/* not version */
+
+table.genTable td.file,
+table.genTable td.proto {
+	border: none;
+	font-size: medium;
+}
+
+table.genTable td.file {
+	font-family: monospace;
+	font-weight: bold;
+}
+
+div.other .row0 {
+	background-color: white;
+}
+
+div.other .row1 {
+	background-color: #ddf;
+}
+
+table.docTable {
+	border-collapse: collapse;
+	border: 1px solid black;
+}
+
+/* 'everything inc version */
+
+table.docTable td,
+table.docTable th {
+	border: 1px solid gray;
+	padding: 0.25em;
+	font-size: small;
+}
+
+/* not version */
+
+table.docTable td.file,
+table.docTable td.proto {
+	border: none;
+	font-size: medium;
+}
+
+table.docTable td.file {
+	font-family: monospace;
+	font-weight: bold;
+}
+
+abbr {
+	border-bottom: 1px dashed #0B0;
+}
+
+h2.TOC {
+	page-break-before: auto;
+}
+
+body.readme {
+	
+}
+
+caption {
+	font-weight: bold;
+	text-align: left
+}
+
+div.indent {
+	margin-left: 2em
+}
+
+ul.TOC {
+	list-style-type: none;
+	padding-left: 1em;
+	font-size: larger;
+}
+
+ul.TOC li a {
+	font-weight: bold;
+}
+
+ul.TOC li ul li a {
+	font-weight: normal;
+	list-style-type: none;
+	font-size: small;
+}
+
+ul.TOC li ul {
+	margin-left: 0;
+	padding-left: 2em;
+	font-weight: normal;
+	list-style-type: none;
+}
+
+pre.samp,samp {
+	margin-left: 1em;
+	border-style: groove;
+	padding: 1em;
+	display: block;
+	background-color: #EEEEEE
+}
\ No newline at end of file
diff --git a/icu/license.html b/icu/license.html
new file mode 100644
index 0000000..7ae0252
--- /dev/null
+++ b/icu/license.html
@@ -0,0 +1,51 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></meta>
+<title>ICU License - ICU 1.8.1 and later</title>
+</head>
+
+<body BGCOLOR="#ffffff">
+<h2>ICU License - ICU 1.8.1 and later</h2>
+
+<p>COPYRIGHT AND PERMISSION NOTICE</p>
+
+<p>
+Copyright (c) 1995-2010 International Business Machines Corporation and others
+</p>
+<p>
+All rights reserved.
+</p>
+<p>
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, and/or sell
+copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies
+of the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+</p>
+<p>
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL
+THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM,
+OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
+USE OR PERFORMANCE OF THIS SOFTWARE.
+</p>
+<p>
+Except as contained in this notice, the name of a copyright holder shall not be
+used in advertising or otherwise to promote the sale, use or other dealings in
+this Software without prior written authorization of the copyright holder.
+</p>
+
+<hr>
+<p><small>
+All trademarks and registered trademarks mentioned herein are the property of their respective owners.
+</small></p>
+</body>
+</html>
diff --git a/icu/packaging/PACKAGES b/icu/packaging/PACKAGES
new file mode 100644
index 0000000..12b3523
--- /dev/null
+++ b/icu/packaging/PACKAGES
@@ -0,0 +1,159 @@
+Copyright (C) 2000-2003, International Business Machines
+Corporation and others.  All Rights Reserved.
+ICU is packaged into a number of small, interdependent packages. This
+file describes what these packages are, what their name should be
+like, and what their contents are. It is useful as a reference and a
+guide when packaging ICU on a new system.
+
++ List of ICU packages.
+
+ICU is distributed as the following packages:
+
+- ICU libraries. This package contains the runtime libraries needed by
+applications that use ICU. All the other packages require this package
+to be installed.
+- ICU. This package contains the converters data, the timezones data,
+and all the ICU tools.
+- ICU locales. This package adds locales and break data.
+- ICU development. This package contains the files necessary to build
+applications that use ICU, i.e. header files, links to shared
+libraries used by the linker, static libraries, etc... It also
+contains sample applications and documentation.
+- ICU docs. This package contains further documentation for ICU,
+including a complete API reference.
+- ICU data. This package contains the source for the compiled data
+contained by the ICU package.
+- ICU international data. This package contains the source for the
+compiled data contained by the ICU locales package.
+
+In this file, we will refer to Autoconf variables as in $(bindir). In
+addition to these, we will use the following variables to denote
+ICU-specific directories or information:
+
+  VERSION       ICU's dotted version number, e.g. 1.6.0.1 as of this
+		writing.
+
+  ICUDATADIR	The directory where portable ICU data are. This is
+	        defined as $(datadir)/icu/$(VERSION).
+  ICULIBDIR	The directory where platform-specific ICU data
+		are. This is defined as $(libdir)/icu/$(VERSION).
+  ICUSYSCONFDIR	The directory where ICU configuration files are. This
+		is defined as $(sysconfdir)/icu.
+
+When referring to libraries, .so will be used to denote the extension
+of a shared library, and .a to denote the extension of a static
+library. These extensions will actually be different on some platforms.
+
++ Configuration and compilation of ICU
+
+ICU should be configured with the following options:
+
+  --with-data-packaging=files
+  --disable-rpath
+  --enable-shared
+  --enable-static
+  --without-samples
+
+in addition to platform-specific settings (like a specific mandir or
+sysconfdir). Note that the use of --disable-rpath assumes that the
+packaging is made for a standard location, or that the package
+installation/deinstallation will correctly manage the configuration
+of the system's dyanmic loader. This is the right way of doing things.
+
+The configure script invokation should also be done with
+
+  CFLAGS="-O2"
+
+set, as in:
+
+  $ CFLAGS="-O2" ./configure ...
+
+The files packaging mode is chosen because it offers the maximum
+flexibility. Packages can be split easily, and system administrators
+can add converters, aliases, and other resources with little
+effort. Ideally, the ICU build will be modified to allow for distributing a
+libicudata.so with all the converters and locales, but indexes and aliases
+as separate files. But for now, this is the easiest way to get started.
+
++ The ICU libraries package
+
+The ICU libraries package is typically named `libicuXX' where XX is
+the major number of ICU's libraries. This number is ICU's version
+number multiplied by 10 and rounded down to the nearest integer (it is
+also the value of the LIB_VERSION_MAJOR configure substitution
+variable). For example, for ICU 1.6.0.1, it is 16, so the package name
+is `libicu16'. The major version is part of the package name to allow
+for the simultaneous installation of different ICU releases.
+
+This package contains:
+
+- All the shared libraries, and their major number symbolic link, but
+not the .so symbolic link that is only used at link time (this one is
+part of the development package). These are $(libdir)/libicu*.so.* and
+$(libdir)/libustdio.so.* at the time of this writing.
+
++ The ICU package
+
+The ICU package is simply named `icu'.  It provides data used by the ICU
+libraries package and commands to create and manipulate that data.
+
+This package contains:
+
+- The Unicode data files (uprops.dat and unames.dat as of this writing).
+- The time zones data files (tz.dat).
+- All the binary data files for converters (.cnv files).
+- All the ICU commands.
+- The manual pages for ICU commands and file formats.
+
++ The ICU locales package
+
+The ICU locales package is named `icu-locales'. It provides data used by
+internationalization support in ICU.
+
+This package contains:
+
+- All the data for locales in ICU (.dat files).
+- All the break data for specific locales (.brk files).
+
++ The ICU development package
+
+The ICU developpment package is named `libicu-dev'. It provides all
+the files necessary to write applications that use ICU, along with
+examples and some documentation.
+
+This package contains:
+
+- The /usr/include/unicode directory which contains all the ICU
+headers.
+- The .so symbolic links used by the linker to link against the
+latest version of the libraries.
+- A sample Makefile fragment that can be included by applications
+using ICU, to faciliate their building, along with a platform-specific
+configuration file included by this fragment.
+- The sample applications from the ICU source tree, in an appropriate
+location for the system that the package is installed on (for example,
+on Debian, in /usr/share/doc/libicu-dev/examples).
+
+This package depends on the ICU libraries package with the exact same
+version, since it provides .so symbolic links to the latest libraries.
+
++ The ICU docs package
+
+The ICU docs package is named `libicu-doc'. It contains the files
+generated by doxygen when the `make doc' command is executed, in a
+location appropriate for the system that the package is installed on.
+
++ The ICU data package
+
+The ICU data package is named `icu-data'. It contains source files for
+the data found in the ICU package. These files are installed in
+$(ICUDATADIR).
+
++ The ICU international data package
+
+The ICU data package is named `icu-i18ndata'. It contains source files for
+the dat founf in the ICU locales package. These files are installed in
+$(ICUDATADIR).
+
+----
+Yves Arrouye <yves@realnames.com>
diff --git a/icu/packaging/README b/icu/packaging/README
new file mode 100644
index 0000000..1bfe85a
--- /dev/null
+++ b/icu/packaging/README
@@ -0,0 +1,13 @@
+Copyright (C) 2000-2003, International Business Machines
+Corporation and others.  All Rights Reserved.
+
+This directory contains information, input files and scripts for
+packaging ICU using specific packaging tools. We assume that the
+packager is familiar with the tools and procedures needed to build a
+package for a given packaging method (for example, how to use
+dpkg-buildpackage(1) on Debian GNU/Linux, or rpm(8) on distributions that
+use RPM packages).
+
+Please read the file PACKAGES if you are interested in packaging ICU
+yourself. It describes what the different packages should be, and what
+their contents are.
diff --git a/icu/packaging/rpm/icu.spec b/icu/packaging/rpm/icu.spec
new file mode 100644
index 0000000..6a1e63b
--- /dev/null
+++ b/icu/packaging/rpm/icu.spec
@@ -0,0 +1,228 @@
+#   Copyright (C) 2000-2005, International Business Machines
+#   Corporation and others.  All Rights Reserved.
+#
+# RPM specification file for ICU.
+#
+# Neal Probert <nprobert@walid.com> is the current maintainer.
+# Yves Arrouye <yves@realnames.com> is the original author.
+
+# This file can be freely redistributed under the same license as ICU.
+
+Name: icu
+Version: 3.4
+Release: 1
+Requires: libicu34 >= %{version}
+Summary: International Components for Unicode
+Packager: Ian Holsman (CNET Networks) <ianh@cnet.com>
+Copyright: X License
+Group: System Environment/Libraries
+Source: icu-%{version}.tgz
+BuildRoot: /var/tmp/%{name}-%{version}
+%description
+ICU is a set of C and C++ libraries that provides robust and full-featured
+Unicode and locale support. The library provides calendar support, conversions
+for many character sets, language sensitive collation, date
+and time formatting, support for many locales, message catalogs
+and resources, message formatting, normalization, number and currency
+formatting, time zones support, transliteration, word, line and
+sentence breaking, etc.
+
+This package contains the Unicode character database and derived
+properties, along with converters and time zones data.
+
+This package contains the runtime libraries for ICU. It does
+not contain any of the data files needed at runtime and present in the
+`icu' and `icu-locales` packages.
+
+%package -n libicu34
+Summary: International Components for Unicode (libraries)
+Group: Development/Libraries
+%description -n libicu34
+ICU is a set of C and C++ libraries that provides robust and full-featured
+Unicode support. This package contains the runtime libraries for ICU. It does
+not contain any of the data files needed at runtime and present in the
+`icu' and `icu-locales` packages.
+
+%package -n libicu-devel
+Summary: International Components for Unicode (development files)
+Group: Development/Libraries
+Requires: libicu34 = %{version}
+%description -n libicu-devel
+ICU is a set of C and C++ libraries that provides robust and full-featured
+Unicode support. This package contains the development files for ICU.
+
+%package locales
+Summary: Locale data for ICU
+Group: System Environment/Libraries
+Requires: libicu34 >= %{version}
+%description locales
+The locale data are used by ICU to provide localization (l10n), 
+internationalization (i18n) and timezone support to ICU applications.
+This package also contains break data for various languages,
+and transliteration data.
+
+%post
+# Adjust the current ICU link in /usr/lib/icu
+
+icucurrent=`2>/dev/null ls -dp /usr/lib/icu/* | sed -n 's,.*/\([^/]*\)/$,\1,p'| sort -rn | head -1`
+cd /usr/lib/icu
+rm -f /usr/lib/icu/current
+if test x"$icucurrent" != x
+then
+    ln -s "$icucurrent" current
+fi
+
+#ICU_DATA=/usr/share/icu/%{version}
+#export ICU_DATA
+
+%preun
+# Adjust the current ICU link in /usr/lib/icu
+
+icucurrent=`2>/dev/null ls -dp /usr/lib/icu/* | sed -n -e '/\/%{version}\//d' -e 's,.*/\([^/]*\)/$,\1,p'| sort -rn | head -1`
+cd /usr/lib/icu
+rm -f /usr/lib/icu/current
+if test x"$icucurrent" != x
+then
+    ln -s "$icucurrent" current
+fi
+
+%post -n libicu34
+ldconfig
+
+# Adjust the current ICU link in /usr/lib/icu
+
+icucurrent=`2>/dev/null ls -dp /usr/lib/icu/* | sed -n 's,.*/\([^/]*\)/$,\1,p'| sort -rn | head -1`
+cd /usr/lib/icu
+rm -f /usr/lib/icu/current
+if test x"$icucurrent" != x
+then
+    ln -s "$icucurrent" current
+fi
+
+%preun -n libicu34
+# Adjust the current ICU link in /usr/lib/icu
+
+icucurrent=`2>/dev/null ls -dp /usr/lib/icu/* | sed -n -e '/\/%{version}\//d' -e 's,.*/\([^/]*\)/$,\1,p'| sort -rn | head -1`
+cd /usr/lib/icu
+rm -f /usr/lib/icu/current
+if test x"$icucurrent" != x
+then
+    ln -s "$icucurrent" current
+fi
+
+%prep
+%setup -q -n icu
+
+%build
+cd source
+chmod a+x ./configure
+CFLAGS="-O3" CXXFLAGS="-O" ./configure --prefix=/usr --sysconfdir=/etc --with-data-packaging=files --enable-shared --enable-static --disable-samples
+echo 'CPPFLAGS += -DICU_DATA_DIR=\"/usr/share/icu/%{version}\"' >> icudefs.mk
+make RPM_OPT_FLAGS="$RPM_OPT_FLAGS"
+
+%install
+rm -rf $RPM_BUILD_ROOT
+cd source
+make install DESTDIR=$RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+%doc readme.html
+%doc license.html
+/usr/share/icu/%{version}/license.html
+/usr/share/icu/%{version}/icudt34l/*.cnv
+/usr/share/icu/%{version}/icudt34l/*.icu
+/usr/share/icu/%{version}/icudt34l/*.spp
+
+/usr/bin/derb
+/usr/bin/genbrk
+/usr/bin/gencnval
+/usr/bin/genrb
+/usr/bin/icu-config
+/usr/bin/makeconv
+/usr/bin/pkgdata
+/usr/bin/uconv
+
+/usr/sbin/decmn
+/usr/sbin/genccode
+/usr/sbin/gencmn
+/usr/sbin/gensprep
+/usr/sbin/genuca
+/usr/sbin/icuswap
+/usr/share/icu/%{version}/mkinstalldirs
+
+/usr/man/man1/derb.1.*
+/usr/man/man1/gencnval.1.*
+/usr/man/man1/genrb.1.*
+/usr/man/man1/icu-config.1.*
+/usr/man/man1/makeconv.1.*
+/usr/man/man1/pkgdata.1.*
+/usr/man/man1/uconv.1.*
+/usr/man/man8/decmn.8.*
+/usr/man/man8/genccode.8.*
+/usr/man/man8/gencmn.8.*
+/usr/man/man8/gensprep.8.*
+/usr/man/man8/genuca.8.*
+
+%files -n icu-locales
+/usr/share/icu/%{version}/icudt34l/*.brk
+/usr/share/icu/%{version}/icudt34l/*.res
+/usr/share/icu/%{version}/icudt34l/coll/*.res
+/usr/share/icu/%{version}/icudt34l/rbnf/*.res
+/usr/share/icu/%{version}/icudt34l/translit/*.res
+
+%files -n libicu34
+%doc license.html
+/usr/lib/libicui18n.so.34
+/usr/lib/libicui18n.so.34.0
+/usr/lib/libicutu.so.34
+/usr/lib/libicutu.so.34.0
+/usr/lib/libicuuc.so.34
+/usr/lib/libicuuc.so.34.0
+/usr/lib/libicudata.so.34
+/usr/lib/libicudata.so.34.0
+/usr/lib/libicuio.so.34
+/usr/lib/libicuio.so.34.0
+/usr/lib/libiculx.so.34
+/usr/lib/libiculx.so.34.0
+/usr/lib/libicule.so.34
+/usr/lib/libicule.so.34.0
+
+%files -n libicu-devel
+%doc readme.html
+%doc license.html
+/usr/lib/libicui18n.so
+/usr/lib/libsicui18n.a
+/usr/lib/libicuuc.so
+/usr/lib/libsicuuc.a
+/usr/lib/libicutu.so
+/usr/lib/libsicutu.a
+/usr/lib/libicuio.so
+/usr/lib/libsicuio.a
+/usr/lib/libicudata.so
+/usr/lib/libsicudata.a
+/usr/lib/libicule.so
+/usr/lib/libsicule.a
+/usr/lib/libiculx.so
+/usr/lib/libsiculx.a
+/usr/include/unicode/*.h
+/usr/include/layout/*.h
+/usr/lib/icu/%{version}/Makefile.inc
+/usr/lib/icu/Makefile.inc
+/usr/share/icu/%{version}/config
+/usr/share/doc/icu-%{version}/*
+
+%changelog
+* Mon Jun 07 2004 Alexei Dets <adets@idsk.com>
+- update to 3.0
+* Tue Aug 16 2003 Steven Loomis <srl@jtcsv.com>
+- update to 2.6.1 - include license
+* Thu Jun 05 2003 Steven Loomis <srl@jtcsv.com>
+- Update to 2.6
+* Fri Dec 27 2002 Steven Loomis <srl@jtcsv.com>
+- Update to 2.4 spec
+* Fri Sep 27 2002 Steven Loomis <srl@jtcsv.com>
+- minor updates to 2.2 spec. Rpath is off by default, don't pass it as an option.
+* Mon Sep 16 2002 Ian Holsman <ian@holsman.net> 
+- update to icu 2.2
+
diff --git a/icu/readme.html b/icu/readme.html
new file mode 100644
index 0000000..a48235e
--- /dev/null
+++ b/icu/readme.html
@@ -0,0 +1,1900 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
+  <head>
+
+    <title>ReadMe for ICU 4.4.1</title>
+    <meta name="COPYRIGHT" content=
+    "Copyright (c) 1997-2010 IBM Corporation and others. All Rights Reserved." />
+    <meta name="KEYWORDS" content=
+    "ICU; International Components for Unicode; ICU4C; what's new; readme; read me; introduction; downloads; downloading; building; installation;" />
+    <meta name="DESCRIPTION" content=
+    "The introduction to the International Components for Unicode with instructions on building, installation, usage and other information about ICU." />
+    <meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
+	<link type="text/css" href="./icu4c.css" rel="stylesheet"/>
+  </head>
+
+  <body>
+    <h1>International Components for Unicode<br />
+     <abbr title="International Components for Unicode">ICU</abbr> 4.4.1 ReadMe</h1>
+
+    <p>Last updated: 2010 Apr 22nd<br />
+     Copyright &copy; 1997-2010 International Business Machines Corporation and
+    others. All Rights Reserved.</p>
+    <!-- Remember that there is a copyright at the end too -->
+    <hr />
+
+    <h2 class="TOC">Table of Contents</h2>
+
+    <ul class="TOC">
+      <li><a href="#Introduction">Introduction</a></li>
+
+      <li><a href="#GettingStarted">Getting Started</a></li>
+
+      <li><a href="#News">What Is New In This release?</a></li>
+
+      <li><a href="#Download">How To Download the Source Code</a></li>
+
+      <li><a href="#SourceCode">ICU Source Code Organization</a></li>
+
+      <li>
+        <a href="#HowToBuild">How To Build And Install ICU</a> 
+
+        <ul >
+          <li><a href="#HowToBuildSupported">Supported Platforms</a></li>
+
+          <li><a href="#RecBuild">Recommended Build Options</a></li>
+
+          <li><a href="#HowToBuildWindows">Windows</a></li>
+
+          <li><a href="#HowToBuildCygwin">Cygwin</a></li>
+
+          <li><a href="#HowToBuildUNIX">UNIX</a></li>
+
+          <li><a href="#HowToBuildZOS">z/OS (os/390)</a></li>
+
+          <li><a href="#HowToBuildOS400">IBM i family (IBM i, i5/OS, OS/400)</a></li>
+
+		  <li><a href="#HowToCrossCompileICU">How to Cross Compile ICU</a></li>
+        </ul>
+      </li>
+
+
+      <li><a href="#HowToPackage">How To Package ICU</a></li>
+
+      <li>
+        <a href="#ImportantNotes">Important Notes About Using ICU</a> 
+
+        <ul >
+          <li><a href="#ImportantNotesMultithreaded">Using ICU in a Multithreaded
+          Environment</a></li>
+
+          <li><a href="#ImportantNotesWindows">Windows Platform</a></li>
+
+          <li><a href="#ImportantNotesUNIX">UNIX Type Platforms</a></li>
+        </ul>
+      </li>
+
+      <li>
+        <a href="#PlatformDependencies">Platform Dependencies</a> 
+
+        <ul >
+          <li><a href="#PlatformDependenciesNew">Porting To A New
+          Platform</a></li>
+
+          <li><a href="#PlatformDependenciesImpl">Platform Dependent
+          Implementations</a></li>
+        </ul>
+      </li>
+    </ul>
+    <hr />
+
+    <h2><a name="Introduction" href="#Introduction" id=
+    "Introduction">Introduction</a></h2>
+
+    <p>Today's software market is a global one in which it is desirable to
+    develop and maintain one application (single source/single binary) that
+    supports a wide variety of languages. The International Components for
+    Unicode (ICU) libraries provide robust and full-featured Unicode services on
+    a wide variety of platforms to help this design goal. The ICU libraries
+    provide support for:</p>
+
+    <ul>
+      <li>The latest version of the Unicode standard</li>
+
+      <li>Character set conversions with support for over 220 codepages</li>
+
+      <li>Locale data for more than 250 locales</li>
+
+      <li>Language sensitive text collation (sorting) and searching based on the
+      Unicode Collation Algorithm (=ISO 14651)</li>
+
+      <li>Regular expression matching and Unicode sets</li>
+
+      <li>Transformations for normalization, upper/lowercase, script
+      transliterations (50+ pairs)</li>
+
+      <li>Resource bundles for storing and accessing localized information</li>
+
+      <li>Date/Number/Message formatting and parsing of culture specific
+      input/output formats</li>
+
+      <li>Calendar specific date and time manipulation</li>
+
+      <li>Complex text layout for Arabic, Hebrew, Indic and Thai</li>
+
+      <li>Text boundary analysis for finding characters, word and sentence
+      boundaries</li>
+    </ul>
+
+    <p>ICU has a sister project ICU4J that extends the internationalization
+    capabilities of Java to a level similar to ICU. The ICU C/C++ project is also
+    called ICU4C when a distinction is necessary.</p>
+
+    <h2><a name="GettingStarted" href="#GettingStarted" id=
+    "GettingStarted">Getting started</a></h2>
+
+    <p>This document describes how to build and install ICU on your machine. For
+    other information about ICU please see the following table of links.<br />
+     The ICU homepage also links to related information about writing
+    internationalized software.</p>
+
+    <table class="docTable" summary="These are some useful links regarding ICU and internationalization in general.">
+      <caption>
+        Here are some useful links regarding ICU and internationalization in
+        general.
+      </caption>
+
+      <tr>
+        <td>ICU, ICU4C &amp; ICU4J Homepage</td>
+
+        <td><a href=
+        "http://icu-project.org/">http://icu-project.org/</a></td>
+      </tr>
+
+      <tr>
+        <td>FAQ - Frequently Asked Questions about ICU</td>
+
+        <td><a href=
+        "http://userguide.icu-project.org/icufaq">http://userguide.icu-project.org/icufaq</a></td>
+      </tr>
+
+      <tr>
+        <td>ICU User's Guide</td>
+
+        <td><a href=
+        "http://userguide.icu-project.org/">http://userguide.icu-project.org/</a></td>
+      </tr>
+
+      <tr>
+        <td>Download ICU Releases</td>
+
+        <td><a href=
+        "http://site.icu-project.org/download">http://site.icu-project.org/download</a></td>
+      </tr>
+
+      <tr>
+        <td>ICU4C API Documentation Online</td>
+
+        <td><a href=
+        "http://icu-project.org/apiref/icu4c/">http://icu-project.org/apiref/icu4c/</a></td>
+      </tr>
+
+      <tr>
+        <td>Online ICU Demos</td>
+
+        <td><a href=
+        "http://demo.icu-project.org/icu-bin/icudemos">http://demo.icu-project.org/icu-bin/icudemos</a></td>
+      </tr>
+
+      <tr>
+        <td>Contacts and Bug Reports/Feature Requests</td>
+
+        <td><a href=
+        "http://site.icu-project.org/contacts">http://site.icu-project.org/contacts</a></td>
+      </tr>
+    </table>
+
+    <p><strong>Important:</strong> Please make sure you understand the <a href=
+    "license.html">Copyright and License Information</a>.</p>
+
+    <h2><a name="News" href="#News" id="News">What is new in this
+    release?</a></h2>
+
+    <p>To see which APIs are new or changed in this release, view the <a href="APIChangeReport.html">ICU4C API Change Report</a>. </p>
+
+    <p><!-- The following list concentrates on <em>changes that affect existing
+    applications migrating from previous ICU releases</em>. --> For more news about
+    this release, see the <a href="http://site.icu-project.org/download">ICU
+    download page</a>.</p>
+
+    <h2><a name="Download" href="#Download" id="Download">How To Download the
+    Source Code</a></h2>
+
+    <p>There are two ways to download ICU releases:</p>
+
+    <ul>
+      <li><strong>Official Release Snapshot:</strong><br />
+       If you want to use ICU (as opposed to developing it), you should download
+      an official packaged version of the ICU source code. These versions are
+      tested more thoroughly than day-to-day development builds of the system,
+      and they are packaged in zip and tar files for convenient download. These
+      packaged files can be found at <a href=
+      "http://site.icu-project.org/download">http://site.icu-project.org/download</a>.<br />
+       The packaged snapshots are named <strong>icu-nnnn.zip</strong> or
+      <strong>icu-nnnn.tgz</strong>, where nnnn is the version number. The .zip
+      file is used for Windows platforms, while the .tgz file is preferred on
+      most other platforms.<br />
+       Please unzip this file. </li>
+
+      <li><strong>Subversion Source Repository:</strong><br />
+       If you are interested in developing features, patches, or bug fixes for
+      ICU, you should probably be working with the latest version of the ICU
+      source code. You will need to check the code out of our Subversion repository to
+      ensure that you have the most recent version of all of the files. See our
+      <a href="http://site.icu-project.org/repository">source
+      repository</a> for details.</li>
+    </ul>
+
+    <h2><a name="SourceCode" href="#SourceCode" id="SourceCode">ICU Source Code
+    Organization</a></h2>
+
+    <p>In the descriptions below, <strong><i>&lt;ICU&gt;</i></strong> is the full
+    path name of the ICU directory (the top level directory from the distribution
+    archives) in your file system. You can also view the <a href=
+    "http://userguide.icu-project.org/design">ICU Architectural
+    Design</a> section of the User's Guide to see which libraries you need for
+    your software product. You need at least the data (<code>[lib]icudt</code>)
+    and the common (<code>[lib]icuuc</code>) libraries in order to use ICU.</p>
+
+    <table class="docTable" summary="The following files describe the code drop.">
+      <caption>
+        The following files describe the code drop.
+      </caption>
+
+      <tr>
+        <th scope="col">File</th>
+
+        <th scope="col">Description</th>
+      </tr>
+
+      <tr>
+        <td>readme.html</td>
+
+        <td>Describes the International Components for Unicode (this file)</td>
+      </tr>
+
+      <tr>
+        <td>license.html</td>
+
+        <td>Contains the text of the ICU license</td>
+      </tr>
+    </table>
+
+    <p><br />
+    </p>
+
+    <table class="docTable" summary=
+    "The following directories contain source code and data files.">
+      <caption>
+        The following directories contain source code and data files.
+      </caption>
+
+      <tr>
+        <th scope="col">Directory</th>
+
+        <th scope="col">Description</th>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/source/<b>common</b>/</td>
+
+        <td>The core Unicode and support functionality, such as resource bundles,
+        character properties, locales, codepage conversion, normalization,
+        Unicode properties, Locale, and UnicodeString.</td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/source/<b>i18n</b>/</td>
+
+        <td>Modules in i18n are generally the more data-driven, that is to say
+        resource bundle driven, components. These deal with higher-level
+        internationalization issues such as formatting, collation, text break
+        analysis, and transliteration.</td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/source/<b>layout</b>/</td>
+
+        <td>Contains the ICU layout engine (not a rasterizer).</td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/source/<b>io</b>/</td>
+
+        <td>Contains the ICU I/O library.</td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/source/<b>data</b>/</td>
+
+        <td>
+          <p>This directory contains the source data in text format, which is
+          compiled into binary form during the ICU build process. It contains
+          several subdirectories, in which the data files are grouped by
+          function. Note that the build process must be run again after any
+          changes are made to this directory.</p>
+
+          <p>If some of the following directories are missing, it's probably
+          because you got an official download. If you need the data source files
+          for customization, then please download the ICU source code from <a
+          href="http://site.icu-project.org/repository">subversion</a>.</p>
+
+          <ul>
+            <li><b>in/</b> A directory that contains a pre-built data library for
+            ICU. A standard source code package will contain this file without
+            several of the following directories. This is to simplify the build
+            process for the majority of users and to reduce platform porting
+            issues.</li>
+
+            <li><b>brkitr/</b> Data files for character, word, sentence, title
+            casing and line boundary analysis.</li>
+
+            <li><b>locales/</b> These .txt files contain ICU language and
+            culture-specific localization data. Two special bundles are
+            <b>root</b>, which is the fallback data and parent of other bundles,
+            and <b>index</b>, which contains a list of installed bundles. The
+            makefile <b>resfiles.mk</b> contains the list of resource bundle
+            files.</li>
+
+            <li><b>mappings/</b> Here are the code page converter tables. These
+            .ucm files contain mappings to and from Unicode. These are compiled
+            into .cnv files. <b>convrtrs.txt</b> is the alias mapping table from
+            various converter name formats to ICU internal format and vice versa.
+            It produces cnvalias.icu. The makefiles <b>ucmfiles.mk,
+            ucmcore.mk,</b> and <b>ucmebcdic.mk</b> contain the list of
+            converters to be built.</li>
+
+            <li><b>translit/</b> This directory contains transliterator rules as
+            resource bundles, a makefile <b>trnsfiles.mk</b> containing the list
+            of installed system translitaration files, and as well the special
+            bundle <b>translit_index</b> which lists the system transliterator
+            aliases.</li>
+
+            <li><b>unidata/</b> This directory contains the Unicode data files.
+            Please see <a href=
+            "http://www.unicode.org/">http://www.unicode.org/</a> for more
+            information.</li>
+
+            <li><b>misc/</b> The misc directory contains other data files which
+            did not fit into the above categories. Currently it only contains
+            time zone information, and a name preperation file for <a href=
+            "http://www.ietf.org/rfc/rfc3490.txt">IDNA</a>.</li>
+
+            <li><b>out/</b> This directory contains the assembled memory mapped
+            files.</li>
+
+            <li><b>out/build/</b> This directory contains intermediate (compiled)
+            files, such as .cnv, .res, etc.</li>
+          </ul>
+
+          <p>If you are creating a special ICU build, you can set the ICU_DATA
+          environment variable to the out/ or the out/build/ directories, but
+          this is generally discouraged because most people set it incorrectly.
+          You can view the <a href=
+          "http://userguide.icu-project.org/icudata">ICU Data
+          Management</a> section of the ICU User's Guide for details.</p>
+        </td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/source/test/<b>intltest</b>/</td>
+
+        <td>A test suite including all C++ APIs. For information about running
+        the test suite, see the build instructions specific to your platform
+        later in this document.</td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/source/test/<b>cintltst</b>/</td>
+
+        <td>A test suite written in C, including all C APIs. For information
+        about running the test suite, see the build instructions specific to your
+        platform later in this document.</td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/source/test/<b>iotest</b>/</td>
+
+        <td>A test suite written in C and C++ to test the icuio library. For
+        information about running the test suite, see the build instructions
+        specific to your platform later in this document.</td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/source/test/<b>testdata</b>/</td>
+
+        <td>Source text files for data, which are read by the tests. It contains
+        the subdirectories <b>out/build/</b> which is used for intermediate
+        files, and <b>out/</b> which contains <b>testdata.dat.</b></td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/source/<b>tools</b>/</td>
+
+        <td>Tools for generating the data files. Data files are generated by
+        invoking <i>&lt;ICU&gt;</i>/source/data/build/makedata.bat on Win32 or
+        <i>&lt;ICU&gt;</i>/source/make on UNIX.</td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/source/<b>samples</b>/</td>
+
+        <td>Various sample programs that use ICU</td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/source/<b>extra</b>/</td>
+
+        <td>Non-supported API additions. Currently, it contains the 'uconv' tool
+        to perform codepage conversion on files.</td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/<b>packaging</b>/</td>
+
+        <td>This directory contain scripts and tools for packaging the final
+        ICU build for various release platforms.</td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/source/<b>config</b>/</td>
+
+        <td>Contains helper makefiles for platform specific build commands. Used
+        by 'configure'.</td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/source/<b>allinone</b>/</td>
+
+        <td>Contains top-level ICU workspace and project files, for instance to
+        build all of ICU under one MSVC project.</td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/<b>include</b>/</td>
+
+        <td>Contains the headers needed for developing software that uses ICU on
+        Windows.</td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/<b>lib</b>/</td>
+
+        <td>Contains the import libraries for linking ICU into your Windows
+        application.</td>
+      </tr>
+
+      <tr>
+        <td><i>&lt;ICU&gt;</i>/<b>bin</b>/</td>
+
+        <td>Contains the libraries and executables for using ICU on Windows.</td>
+      </tr>
+    </table>
+    <!-- end of ICU structure ==================================== -->
+
+    <h2><a name="HowToBuild" href="#HowToBuild" id="HowToBuild">How To Build And
+    Install ICU</a></h2>
+
+    <h3><a name="HowToBuildSupported" href="#HowToBuildSupported" id=
+    "HowToBuildSupported">Supported Platforms</a></h3>
+
+    <table class="rtable" summary=
+    "ICU can be built on many platforms.">
+      <caption>
+        Here is the status of building ICU on several different platforms.
+      </caption>
+
+        
+            <tr>
+                <td>AIX 6.1 (power, 64-bit)</td>
+                <td>VisualAge 9</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>HP/UX 11iv3 (ia64, 64-bit)</td>
+                <td>aCC A.06.15</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>Red Hat Enterprise Linux 5 (x86, 32-bit)</td>
+                <td>gcc 4.1.2</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>Red Hat Enterprise Linux 5 (x86, 64-bit)</td>
+                <td>gcc 4.1.2</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>Solaris 10 (sparc, 64-bit)</td>
+                <td>Sun Studio 12</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>Windows Vista SP1 (x86, 32-bit)</td>
+                <td>MS Visual Studio 9</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>AIX 5.2 (power, 64-bit)</td>
+                <td>VisualAge 6</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>AIX 5.3 (power, 64-bit)</td>
+                <td>VisualAge 8</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>AIX 6.1 (power, 64-bit)</td>
+                <td>gcc 4.2.4</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>HP/UX 11i (hppa, 64-bit)</td>
+                <td>aCC A.03.85</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>MacOSX 10.5 Leopard (x86, 32-bit)</td>
+                <td>gcc 4.0.1</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>MacOSX 10.5 Leopard (x86, 64-bit)</td>
+                <td>gcc 4.0.1</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>Red Hat Enterprise Linux 4.2 (x86, 32-bit)</td>
+                <td>gcc 3.4.6</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>Red Hat Enterprise Linux 4u7 (x86, 32-bit)</td>
+                <td>gcc 4.2.4</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+
+            <tr>
+                <td>Red Hat Enterprise Linux 5 (x86, 32-bit)</td>
+                <td>icc 11.0</td>
+                <td class="works">Frequently Tested<br/><b>[<a href="#LinuxICCValueSafeOptimization">See Change</a>]</b></td>
+            </tr>
+
+            <tr>
+                <td>Solaris 10 (sparc, 64-bit)</td>
+                <td>gcc 4.2.1</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>SuSE 10 (x86, 64-bit)</td>
+                <td>gcc 4.1.0</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>Windows 2000 Professional (x86, 32-bit)</td>
+                <td>MS Visual Studio 2003 via Cygwin</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>Windows 2000 Professional (x86, 32-bit)</td>
+                <td>gcc 3.4.4 via Cygwin</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>Windows Server 2003 (x86, 64-bit)</td>
+                <td>MS Visual Studio 8 via Cygwin</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>Windows Server 2008 (x86, 64-bit)</td>
+                <td>MS Visual Studio 9</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr>
+                <td>Windows XP Professional (x86, 32-bit)</td>
+                <td>MS Visual Studio 9</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+            
+            <tr>
+                <td>Windows Server 2008 (x86, 64-bit)</td>
+                <td>MS Visual Studio 9 via Cygwin</td>
+                <td class="works">Frequently Tested</td>
+
+            </tr>
+        
+            <tr class="broken">
+                <td>SuSe Linux 7.2 (x86, 32-bit)</td>
+                <td>icc 9.0</td>
+                <td class="broken">Broken <b><a href="http://bugs.icu-project.org/trac/ticket/6888">#6888</a></b></td>
+
+            </tr>
+        
+
+<!-- end IBM lab data -->
+
+      <tr class="rarely">
+        <td>z/OS 1.7</td>
+
+        <td>cxx 1.7</td>
+
+        <td>Rarely tested</td>
+      </tr>
+
+      <tr class="rarely">
+        <td>IBM i family (IBM i, i5/OS, OS/400)</td>
+
+        <td>iCC</td>
+
+        <td>Rarely tested</td>
+      </tr>
+
+
+      <tr class="rarely">
+        <td>MinGW</td>
+
+        <td>gcc</td>
+
+        <td>Rarely tested</td>
+      </tr>
+
+      <tr class="rarely">
+        <td>NetBSD, OpenBSD, FreeBSD</td>
+
+        <td>gcc</td>
+
+        <td>Rarely tested</td>
+      </tr>
+
+      <tr class="rarely">
+        <td>SUSE Linux Enterprise Server 9 (PowerPC)</td>
+
+        <td>IBM XL C/C++ 8.0</td>
+
+        <td>Rarely tested</td>
+      </tr>
+
+      <tr class="rarely">
+        <td>QNX</td>
+
+        <td>gcc</td>
+
+        <td>Rarely tested</td>
+      </tr>
+
+      <tr class="rarely">
+        <td>BeOS/Haiku</td>
+
+        <td>gcc</td>
+
+        <td>Rarely tested</td>
+      </tr>
+
+      <tr class="rarely">
+        <td>SGI/IRIX</td>
+
+        <td>MIPSpro CC</td>
+
+        <td>Rarely tested</td>
+      </tr>
+
+      <tr class="rarely">
+        <td>Tru64 (OSF)</td>
+
+        <td>Compaq's cxx compiler</td>
+
+        <td>Rarely tested</td>
+      </tr>
+
+      <tr class="rarely">
+        <td>MP-RAS</td>
+
+        <td>NCR MP-RAS C/C++ Compiler</td>
+
+        <td>Rarely tested</td>
+      </tr>
+    </table>
+
+    <p><br />
+    </p>
+
+    <h4>Key to testing frequency</h4>
+
+    <dl>
+      <dt><i>Frequently tested</i></dt>
+
+      <dd>ICU will work on these platforms with these compilers</dd>
+
+      <dt><i>Rarely tested</i></dt>
+
+      <dd>ICU has been ported to these platforms but may not have been tested
+      there recently</dd>
+    </dl>
+
+    <h3><a name="RecBuild" href="#RecBuild" id=
+    "RecBuild">Recommended Build Options</a></h3>
+
+    <p>Depending on the platform and the type of installation,
+    we recommend a small number of modifications and build options.</p>
+    <ul>
+      <li><b>Namespace:</b> By default, unicode/uversion.h has
+        "using namespace icu;" which defeats much of the purpose of the namespace.
+        (This is for historical reasons: Originally, ICU4C did not use namespaces,
+        and some compilers did not support them. The default "using" statement
+        preserves source code compatibility.)<br>
+        We recommend you turn this off via <code>-DU_USING_ICU_NAMESPACE=0</code>
+        or by modifying unicode/uversion.h:
+<pre>Index: source/common/unicode/uversion.h
+===================================================================
+--- source/common/unicode/uversion.h    (revision 26606)
++++ source/common/unicode/uversion.h    (working copy)
+@@ -180,7 +180,8 @@
+ #   define U_NAMESPACE_QUALIFIER U_ICU_NAMESPACE::
+
+ #   ifndef U_USING_ICU_NAMESPACE
+-#       define U_USING_ICU_NAMESPACE 1
++        // Set to 0 to force namespace declarations in ICU usage.
++#       define U_USING_ICU_NAMESPACE 0
+ #   endif
+ #   if U_USING_ICU_NAMESPACE
+         U_NAMESPACE_USE
+</pre>
+        ICU call sites then either qualify ICU types explicitly,
+        for example <code>icu::UnicodeString</code>,
+        or do <code>using icu::UnicodeString;</code> where appropriate.</li>
+      <li><b>Hardcode the default charset to UTF-8:</b> On platforms where
+        the default charset is always UTF-8,
+        like MacOS X and some Linux distributions,
+        we recommend hardcoding ICU's default charset to UTF-8.
+        This means that some implementation code becomes simpler and faster,
+        and statically linked ICU libraries become smaller.
+        (See the <a href="http://icu-project.org/apiref/icu4c/utypes_8h.html#0a33e1edf3cd23d9e9c972b63c9f7943">U_CHARSET_IS_UTF8</a>
+        API documentation for more details.)<br>
+        You can <code>-DU_CHARSET_IS_UTF8=1</code> or modify unicode/utypes.h:
+<pre>Index: source/common/unicode/utypes.h
+===================================================================
+--- source/common/unicode/utypes.h      (revision 26606)
++++ source/common/unicode/utypes.h      (working copy)
+@@ -160,7 +160,7 @@
+  * @see UCONFIG_NO_CONVERSION
+  */
+ #ifndef U_CHARSET_IS_UTF8
+-#   define U_CHARSET_IS_UTF8 0
++#   define U_CHARSET_IS_UTF8 1
+ #endif
+
+ /*===========================================================================*/
+</pre></li>
+      <li><b>.dat file:</b> By default, the ICU data is built into
+        a shared library (DLL). This is convenient because it requires no
+        install-time or runtime configuration,
+        but the library is platform-specific and cannot be modified.
+        A .dat package file makes the opposite trade-off:
+        Platform-portable (except for endianness and charset family, which
+        can be changed with the icupkg tool)
+        and modifiable (also with the icupkg tool).
+        If a path is set, then single data files (e.g., .res files)
+        can be copied to that location to provide new locale data
+        or conversion tables etc.<br>
+        The only drawback with a .dat package file is that the application
+        needs to provide ICU with the file system path to the package file
+        (e.g., by calling <code>u_setDataDirectory()</code>)
+        or with a pointer to the data (<code>udata_setCommonData()</code>)
+        before other ICU API calls.
+        This is usually easy if ICU is used from an application where
+        <code>main()</code> takes care of such initialization.
+        It may be hard if ICU is shipped with
+        another shared library (such as the Xerces-C++ XML parser)
+        which does not control <code>main()</code>.<br>
+        See the <a href="http://userguide.icu-project.org/icudata">User Guide ICU Data</a>
+        chapter for more details.<br>
+        If possible, we recommend building the .dat package.
+        Specify <code>--with-data-packaging=archive</code>
+        on the configure command line, as in<br>
+        <code>runConfigureICU Linux --with-data-packaging=archive</code><br>
+        (Read the configure script's output for further instructions.
+        On Windows, the Visual Studio build generates both the .dat package
+        and the data DLL.)<br>
+        Be sure to install and use the tiny stubdata library
+        rather than the large data DLL.</li>
+      <li><b>Static libraries:</b> It may make sense to build the ICU code
+        into static libraries (.a) rather than shared libraries (.so/.dll).
+        Static linking reduces the overall size of the binary by removing
+        code that is never called.<br>
+        Example configure command line:<br>
+        <code>runConfigureICU Linux --enable-static --disable-shared</code></li>
+      <li><b>Out-of-source build:</b> It is usually desirable to keep the ICU
+        source file tree clean and have build output files written to
+        a different location. This is called an "out-of-source build".
+        Simply invoke the configure script from the target location:
+<pre>~/icu$ svn export http://source.icu-project.org/repos/icu/icu/trunk
+~/icu$ mkdir trunk-dev
+~/icu$ cd trunk-dev
+~/icu/trunk-dev$ ../trunk/source/runConfigureICU Linux
+~/icu/trunk-dev$ make check</pre></li>
+    </ul>
+    <h4>ICU as a System-Level Library</h4>
+    <p>If ICU is installed as a system-level library, there are further
+      opportunities and restrictions to consider.
+      For details, see the <em>Using ICU as an Operating System Level Library</em>
+      section of the <a href="http://userguide.icu-project.org/design">User Guide ICU Architectural Design</a> chapter.</p>
+    <ul>
+      <li><b>Data path:</b> For a system-level library, it is best to load
+        ICU data from the .dat package file because the file system path
+        to the .dat package file can be hardcoded.
+        Set <code>-DICU_DATA_DIR=/path/to/icu/data</code> when building
+        the ICU code. (Used by source/common/putil.c.)<br>
+        Consider also setting <code>-DICU_NO_USER_DATA_OVERRIDE</code>
+        if you do not want the "ICU_DATA" environment variable to be used.
+        (An application can still override the data path via
+        <code>u_setDataDirectory()</code> or
+        <code>udata_setCommonData()</code>.</li>
+      <li><b>Hide draft API:</b> API marked with <code>@draft</code>
+        is new and not yet stable. Applications must not rely on unstable
+        APIs from a system-level library.
+        Define <code>U_HIDE_DRAFT_API</code>, <code>U_HIDE_INTERNAL_API</code>
+        and <code>U_HIDE_SYSTEM_API</code>
+        by modifying unicode/utypes.h before installing it.</li>
+      <li><b>Only C APIs:</b> Applications must not rely on C++ APIs from a
+        system-level library because binary C++ compatibility
+        across library and compiler versions is very hard to achieve.
+        Most ICU C++ APIs are in header files that contain a comment with
+        <code>\brief C++ API</code>.
+        Consider not installing these header files.</li>
+      <li><b>Disable renaming:</b> By default, ICU library entry point names
+        have an ICU version suffix. Turn this off for a system-level installation,
+        to enable upgrading ICU without breaking applications. For example:<br>
+        <code>runConfigureICU Linux --disable-renaming</code><br>
+        The public header files from this configuration must be installed
+        for applications to include and get the correct entry point names.</li>
+    </ul>
+
+    <h3><a name="HowToBuildWindows" href="#HowToBuildWindows" id=
+    "HowToBuildWindows">How To Build And Install On Windows</a></h3>
+
+    <p>Building International Components for Unicode requires:</p>
+
+    <ul>
+      <li>Microsoft Windows 2000 or above</li>
+
+      <li>Microsoft Visual C++ 2008</li>
+
+      <li><a href="#HowToBuildCygwin">Cygwin</a> is required when other versions
+      of Microsoft Visual C++ and other compilers are used to build ICU.</li>
+    </ul>
+
+    <p>The steps are:</p>
+
+    <ol>
+      <li>Unzip the icu-XXXX.zip file into any convenient location. Using command
+      line zip, type "unzip -a icu-XXXX.zip -d drive:\directory", or just use
+      WinZip.</li>
+
+      <li>Be sure that the ICU binary directory, <i>&lt;ICU&gt;</i>\bin\, is
+      included in the <strong>PATH</strong> environment variable. The tests will
+      not work without the location of the ICU DLL files in the path.</li>
+
+      <li>Open the "<i>&lt;ICU&gt;</i>\source\allinone\allinone.sln" workspace
+      file in Microsoft Visual Studio 2003. (This solution includes all the
+      International Components for Unicode libraries, necessary ICU building
+      tools, and the test suite projects). Please see the <a href=
+      "#HowToBuildWindowsCommandLine">command line note below</a> if you want to
+      build from the command line instead.</li>
+
+      <li>Set the active platform to "Win32" or "x64" (See <a href="#HowToBuildWindowsPlatform">Windows platform note</a> below) 
+      and configuration to "Debug" or "Release" (See <a href="#HowToBuildWindowsConfig">Windows configuration note</a> below).</li>
+
+      <li>Choose the "Build" menu and select "Rebuild Solution". If you want to
+      build the Debug and Release at the same time, see the <a href=
+      "#HowToBuildWindowsBatch">batch configuration note</a> below.</li>
+
+      <li>Run the C++ test suite, "intltest". To do this: set the active startup
+      project to "intltest", and press Ctrl+F5 to run it. Make sure that it
+      passes without any errors.</li>
+
+      <li>Run the C test suite, "cintltst". To do this: set the active startup
+      project to "cintltst", and press Ctrl+F5 to run it. Make sure that it
+      passes without any errors.</li>
+
+      <li>Run the I/O test suite, "iotest". To do this: set the active startup
+      project to "iotest", and press Ctrl+F5 to run it. Make sure that it passes
+      without any errors.</li>
+
+      <li>You are now able to develop applications with ICU by using the
+      libraries and tools in <i>&lt;ICU&gt;</i>\bin\. The headers are in
+      <i>&lt;ICU&gt;</i>\include\ and the link libraries are in
+      <i>&lt;ICU&gt;</i>\lib\. To install the ICU runtime on a machine, or ship
+      it with your application, copy the needed components from
+      <i>&lt;ICU&gt;</i>\bin\ to a location on the system PATH or to your
+      application directory.</li>
+    </ol>
+
+    <p><a name="HowToBuildWindowsCommandLine" id=
+    "HowToBuildWindowsCommandLine"><strong>Using MSDEV At The Command Line
+    Note:</strong></a> You can build ICU from the command line. Assuming that you
+    have properly installed Microsoft Visual C++ to support command line
+    execution, you can run the following command, 'devenv.com
+    <i>&lt;ICU&gt;</i>\source\allinone\allinone.sln /build "Win32|Release"'. You can also
+    use Cygwin with this compiler to build ICU, and you can refer to the <a href=
+    "#HowToBuildCygwin">How To Build And Install On Windows with Cygwin</a>
+    section for more details.</p>
+    
+    <p><a name="HowToBuildWindowsPlatform" id=
+    "HowToBuildWindowsPlatform"><strong>Setting Active Platform
+    Note:</strong></a> Even though you are able to select "x64" as the active platform, if your operating system is 
+    not a 64 bit version of Windows, the build will fail. To set the active platform, two different possibilities are:</p>
+
+    <ul>
+      <li>Choose "Build" menu, select "Configuration Manager...", and select
+      "Win32" or "x64" for the Active Platform Solution.</li>
+
+      <li>Another way is to select the desired build configuration from "Solution
+      Platforms" dropdown menu from the standard toolbar. It will say
+      "Win32" or "x64" in the dropdown list.</li>
+    </ul>
+
+    <p><a name="HowToBuildWindowsConfig" id=
+    "HowToBuildWindowsConfig"><strong>Setting Active Configuration
+    Note:</strong></a> To set the active configuration, two different
+    possibilities are:</p>
+
+    <ul>
+      <li>Choose "Build" menu, select "Configuration Manager...", and select
+      "Release" or "Debug" for the Active Configuration Solution.</li>
+
+      <li>Another way is to select the desired build configuration from "Solution
+      Configurations" dropdown menu from the standard toolbar. It will say
+      "Release" or "Debug" in the dropdown list.</li>
+    </ul>
+
+    <p><a name="HowToBuildWindowsBatch" id="HowToBuildWindowsBatch"><strong>Batch
+    Configuration Note:</strong></a> If you want to build the Win32 and x64 platforms and 
+    Debug and Release configurations at the same time, choose "Build" menu, and select "Batch
+    Build...". Click the "Select All" button, and then click the "Rebuild"
+    button.</p>
+
+    <h3><a name="HowToBuildCygwin" href="#HowToBuildCygwin" id=
+    "HowToBuildCygwin">How To Build And Install On Windows with Cygwin</a></h3>
+
+    <p>Building International Components for Unicode with this configuration
+    requires:</p>
+
+    <ul>
+      <li>Microsoft 2000 or above</li>
+
+      <li>Microsoft Visual C++ 2003 or above (when gcc isn't used).</li>
+
+      <li>
+        Cygwin with the following installed: 
+
+        <ul>
+          <li>bash</li>
+
+          <li>GNU make</li>
+
+          <li>ar</li>
+
+          <li>ranlib</li>
+
+          <li>man (if you plan to look at the man pages)</li>
+        </ul>
+      </li>
+    </ul>
+
+    <p>There are two ways you can build ICU with Cygwin. You can build with gcc
+    or Microsoft Visual C++. If you use gcc, the resulting libraries and tools
+    will depend on the Cygwin environment. If you use Microsoft Visual C++, the
+    resulting libraries and tools do not depend on Cygwin and can be more easily
+    distributed to other Windows computers (the generated man pages and shell
+    scripts still need Cygwin). To build with gcc, please follow the "<a href=
+    "#HowToBuildUNIX">How To Build And Install On UNIX</a>" instructions, while
+    you are inside a Cygwin bash shell. To build with Microsoft Visual C++,
+    please use the following instructions:</p>
+
+    <ol>
+      <li>Start the Windows "Command Prompt" window. This is different from the
+      gcc build, which requires the Cygwin Bash command prompt. The Microsoft
+      Visual C++ compiler will not work with a bash command prompt.</li>
+
+      <li>If the computer isn't set up to use Visual C++ from the command line,
+      you need to run vcvars32.bat.<br>For example:<br>"<tt>C:\Program Files\Microsoft
+      Visual Studio 8\VC\bin\vcvars32.bat</tt>" can be used for 32-bit builds
+      <strong>or</strong> <br>"<tt>C:\Program Files (x86)\Microsoft Visual Studio
+      8\VC\bin\amd64\vcvarsamd64.bat</tt>" can be used for 64-bit builds on
+      Windows x64.</li>
+
+      <li>Unzip the icu-XXXX.zip file into any convenient location. Using command
+      line zip, type "unzip -a icu-XXXX.zip -d drive:\directory", or just use
+      WinZip.</li>
+
+      <li>Change directory to "icu/source", which is where you unzipped ICU.</li>
+
+      <li>Run "<tt>bash <a href="source/runConfigureICU">./runConfigureICU</a>
+      Cygwin/MSVC</tt>" (See <a href="#HowToWindowsConfigureICU">Windows
+      configuration note</a> and non-functional configure options below).</li>
+
+      <li>Type <tt>"make"</tt> to compile the libraries and all the data files.
+      This make command should be GNU make.</li>
+
+      <li>Optionally, type <tt>"make check"</tt> to run the test suite, which
+      checks for ICU's functionality integrity (See <a href=
+      "#HowToTestWithoutGmake">testing note</a> below).</li>
+
+      <li>Type <tt>"make install"</tt> to install ICU. If you used the --prefix=
+      option on configure or runConfigureICU, ICU will be installed to the
+      directory you specified. (See <a href="#HowToInstallICU">installation
+      note</a> below).</li>
+    </ol>
+
+    <p><a name="HowToWindowsConfigureICU" id=
+    "HowToWindowsConfigureICU"><strong>Configuring ICU on Windows
+    NOTE:</strong></a> </p>
+    <p>
+    Ensure that the order of the PATH is MSVC, Cygwin, and then other PATHs. The configure 
+    script needs certain tools in Cygwin (e.g. grep).
+    </p>
+    <p>
+    Also, you may need to run <tt>"dos2unix.exe"</tt> on all of the scripts (e.g. configure)
+    in the top source directory of ICU. To avoid this issue, you can download
+    the ICU source for Unix platforms (icu-xxx.tgz).
+    </p>
+    <p>In addition to the Unix <a href=
+    "#HowToConfigureICU">configuration note</a> the following configure options
+    currently do not work on Windows with Microsoft's compiler. Some options can
+    work by manually editing <tt>icu/source/common/unicode/pwin32.h</tt>, but
+    manually editing the files is not recommended.</p>
+
+    <ul>
+      <li><tt>--disable-renaming</tt></li>
+
+      <li><tt>--disable-threading</tt> (This flag does disable threading in ICU,
+      but the resulting ICU library will still be linked with MSVC's multithread DLL)</li>
+
+      <li><tt>--enable-tracing</tt></li>
+
+      <li><tt>--enable-rpath</tt></li>
+
+      <li><tt>--with-iostream</tt></li>
+
+      <li><tt>--enable-static</tt> (Requires that U_STATIC_IMPLEMENTATION be
+      defined in user code that links against ICU's static libraries.)</li>
+
+      <li><tt>--with-data-packaging=files</tt> (The pkgdata tool currently does
+      not work in this mode. Manual packaging is required to use this mode.)</li>
+    </ul>
+
+    <h3><a name="HowToBuildUNIX" href="#HowToBuildUNIX" id="HowToBuildUNIX">How
+    To Build And Install On UNIX</a></h3>
+
+    <p>Building International Components for Unicode on UNIX requires:</p>
+
+    <ul>
+      <li>A C++ compiler installed on the target machine (for example: gcc, CC,
+      xlC_r, aCC, cxx, etc...).</li>
+
+      <li>An ANSI C compiler installed on the target machine (for example:
+      cc).</li>
+
+      <li>A recent version of GNU make (3.80+).</li>
+
+      <li>For a list of z/OS tools please view the <a href="#HowToBuildZOS">z/OS
+      build section</a> of this document for further details.</li>
+    </ul>
+
+    <p>Here are the steps to build ICU:</p>
+
+    <ol>
+      <li>Decompress the icu-<i>X</i>.<i>Y</i>.tgz (or
+      icu-<i>X</i>.<i>Y</i>.tar.gz) file. For example, <tt>"gunzip -d &lt;
+      icu-<i>X</i>.<i>Y</i>.tgz | tar xvf -"</tt></li>
+
+      <li>Change directory to the "icu/source".</li>
+
+      <li>Run <tt>"chmod +x runConfigureICU configure install-sh"</tt> because
+      these files may have the wrong permissions.</li>
+
+      <li>Run the <tt><a href="source/runConfigureICU">runConfigureICU</a></tt>
+      script for your platform. (See <a href="#HowToConfigureICU">configuration
+      note</a> below).</li>
+
+      <li>Type <tt>"gmake"</tt> (or "make" if GNU make is the default make on
+      your platform) to compile the libraries and all the data files. The proper
+      name of the GNU make command is printed at the end of the configuration
+      run, as in "You must use gmake to compile ICU".</li>
+
+      <li>Optionally, type <tt>"gmake check"</tt> to run the test suite, which
+      checks for ICU's functionality integrity (See <a href=
+      "#HowToTestWithoutGmake">testing note</a> below).</li>
+
+      <li>Type <tt>"gmake install"</tt> to install ICU. If you used the --prefix=
+      option on configure or runConfigureICU, ICU will be installed to the
+      directory you specified. (See <a href="#HowToInstallICU">installation
+      note</a> below).</li>
+    </ol>
+
+    <p><a name="HowToConfigureICU" id="HowToConfigureICU"><strong>Configuring ICU
+    NOTE:</strong></a> Type <tt>"./runConfigureICU --help"</tt> for help on how
+    to run it and a list of supported platforms. You may also want to type
+    <tt>"./configure --help"</tt> to print the available configure options that
+    you may want to give runConfigureICU. If you are not using the
+    runConfigureICU script, or your platform is not supported by the script, you
+    may need to set your CC, CXX, CFLAGS and CXXFLAGS environment variables, and
+    type <tt>"./configure"</tt>. 
+    HP-UX users, please see this <a href="#ImportantNotesHPUX">note regarding
+    HP-UX multithreaded build issues</a> with newer compilers. Solaris users,
+    please see this <a href="#ImportantNotesSolaris">note regarding Solaris
+    multithreaded build issues</a>.</p>
+
+    <p>ICU is built with strict compiler warnings enabled by default.  If this
+    causes excessive numbers of warnings on your platform, use the --disable-strict
+    option to configure to reduce the warning level.</p>
+
+    <p><a name="HowToTestWithoutGmake" id="HowToTestWithoutGmake"><strong>Running
+    The Tests From The Command Line NOTE:</strong></a> You may have to set
+    certain variables if you with to run test programs individually, that is
+    apart from "gmake check". The environment variable <strong>ICU_DATA</strong>
+    can be set to the full pathname of the data directory to indicate where the
+    locale data files and conversion mapping tables are when you are not using
+    the shared library (e.g. by using the .dat archive or the individual data
+    files). The trailing "/" is required after the directory name (e.g.
+    "$Root/source/data/out/" will work, but the value "$Root/source/data/out" is
+    not acceptable). You do not need to set <strong>ICU_DATA</strong> if the
+    complete shared data library is in your library path.</p>
+
+    <p><a name="HowToInstallICU" id="HowToInstallICU"><strong>Installing ICU
+    NOTE:</strong></a> Some platforms use package management tools to control the
+    installation and uninstallation of files on the system, as well as the
+    integrity of the system configuration. You may want to check if ICU can be
+    packaged for your package management tools by looking into the "packaging"
+    directory. (Please note that if you are using a snapshot of ICU from Subversion, it
+    is probable that the packaging scripts or related files are not up to date
+    with the contents of ICU at this time, so use them with caution).</p>
+
+    <h3><a name="HowToBuildZOS" href="#HowToBuildZOS" id="HowToBuildZOS">How To
+    Build And Install On z/OS (OS/390)</a></h3>
+
+    <p>You can install ICU on z/OS or OS/390 (the previous name of z/OS), but IBM
+    tests only the z/OS installation. You install ICU in a z/OS UNIX system
+    services file system such as HFS or zFS. On this platform, it is important
+    that you understand a few details:</p>
+
+    <ul>
+      <li>The makedep and GNU make tools are required for building ICU. If it
+      is not already installed on your system, it is available at the <a href=
+      "http://www-03.ibm.com/servers/eserver/zseries/zos/unix/bpxa1toy.html">z/OS UNIX -
+      Tools and Toys</a> site. The PATH environment variable should be updated to
+      contain the location of this executable prior to build. Failure to add these
+      tools to your PATH will cause ICU build failures or cause pkgdata to fail
+      to run.</li>
+
+      <li>Since USS does not support using the mmap() function over NFS, it is
+      recommended that you build ICU on a local filesystem. Once ICU has been
+      built, you should not have this problem while using ICU when the data
+      library has been built as a shared library, which is this is the default
+      setting.</li>
+
+      <li>Encoding considerations: The source code assumes that it is compiled
+      with codepage ibm-1047 (to be exact, the UNIX System Services variant of
+      it). The pax command converts all of the source code files from ASCII to
+      codepage ibm-1047 (USS) EBCDIC. However, some files are binary files and
+      must not be converted, or must be converted back to their original state.
+      You can use the <a href="as_is/os390/unpax-icu.sh">unpax-icu.sh</a> script
+      to do this for you automatically. It will unpackage the tar file and
+      convert all the necessary files for you automatically.</li>
+
+      <li>z/OS supports both native S/390 hexadecimal floating point and (with
+      OS/390 2.6 and later) IEEE 754 binary floating point. This is a compile
+      time option. Applications built with IEEE should use ICU DLLs that are
+      built with IEEE (and vice versa). The environment variable IEEE390=0 will
+      cause the z/OS version of ICU to be built without IEEE floating point
+      support and use the native hexadecimal floating point. By default ICU is
+      built with IEEE 754 support. Native floating point support is sufficient
+      for codepage conversion, resource bundle and UnicodeString operations, but
+      the Format APIs require IEEE binary floating point.</li>
+
+      <li>z/OS introduced the concept of Extra Performance Linkage (XPLINK) to
+      bring performance improvement opportunities to call-intensive C and C++
+      applications such as ICU. XPLINK is enabled on a DLL-by-DLL basis, so if
+      you are considering using XPLINK in your application that uses ICU, you
+      should consider building the XPLINK-enabled version of ICU. You need to
+      set ICU's environment variable <code>OS390_XPLINK=1</code> prior to
+      invoking the make process to produce binaries that are enabled for
+      XPLINK. The XPLINK option, which is available for z/OS 1.2 and later,
+      requires the PTF PQ69418 to build XPLINK enabled binaries.</li>
+
+      <li>Currently in ICU 3.0, there is an issue with building on z/OS without
+      XPLINK and with the C++ iostream. By default, the iostream library on z/OS
+      is XPLINK enabled. If you are not building an XPLINK enabled version of
+      ICU, you should use the <code>--with-iostream=old</code> configure option
+      when using runConfigureICU. This will prevent applications that use the
+      icuio library from crashing.</li>
+
+      <li>The rest of the instructions for building and testing ICU on z/OS with
+      UNIX System Services are the same as the <a href="#HowToBuildUNIX">How To
+      Build And Install On UNIX</a> section.</li>
+    </ul>
+
+    <h4>z/OS (Batch/PDS) support outside the UNIX system services
+    environment</h4>
+
+    <p>By default, ICU builds its libraries into the UNIX file system (HFS). In
+    addition, there is a z/OS specific environment variable (OS390BATCH) to build
+    some libraries into the z/OS native file system. This is useful, for example,
+    when your application is externalized via Job Control Language (JCL).</p>
+
+    <p>The OS390BATCH environment variable enables non-UNIX support including the
+    batch environment. When OS390BATCH is set, the libicui18n<i>XX</i>.dll,
+    libicuuc<i>XX</i>.dll, and libicudt<i>XX</i>e.dll binaries are built into
+    data sets (the native file system). Turning on OS390BATCH does not turn off
+    the normal z/OS UNIX build. This means that the z/OS UNIX (HFS) DLLs will
+    always be created.</p>
+
+    <p>Two additional environment variables indicate the names of the z/OS data
+    sets to use. The LOADMOD environment variable identifies the name of the data
+    set that contains the dynamic link libraries (DLLs) and the LOADEXP
+    environment variable identifies the name of the data set that contains the
+    side decks, which are normally the files with the .x suffix in the UNIX file
+    system.</p>
+
+    <p>A data set is roughly equivalent to a UNIX or Windows file. For most kinds
+    of data sets the operating system maintains record boundaries. UNIX and
+    Windows files are byte streams. Two kinds of data sets are PDS and PDSE. Each
+    data set of these two types contains a directory. It is like a UNIX
+    directory. Each "file" is called a "member". Each member name is limited to
+    eight bytes, normally EBCDIC.</p>
+
+    <p>Here is an example of some environment variables that you can set prior to
+    building ICU:</p>
+<pre>
+<samp>OS390BATCH=1
+LOADMOD=<i>USER</i>.ICU.LOAD
+LOADEXP=<i>USER</i>.ICU.EXP</samp>
+</pre>
+
+    <p>The PDS member names for the DLL file names are as follows:</p>
+<pre>
+<samp>IXMI<i>XX</i>IN --&gt; libicui18n<i>XX</i>.dll
+IXMI<i>XX</i>UC --&gt; libicuuc<i>XX</i>.dll
+IXMI<i>XX</i>DA --&gt; libicudt<i>XX</i>e.dll</samp>
+</pre>
+
+    <p>You should point the LOADMOD environment variable at a partitioned data
+    set extended (PDSE) and point the LOADEXP environment variable at a
+    partitioned data set (PDS). The PDSE can be allocated with the following
+    attributes:</p>
+<pre>
+<samp>Data Set Name . . . : <i>USER</i>.ICU.LOAD
+Management class. . : <i>**None**</i>
+Storage class . . . : <i>BASE</i>
+Volume serial . . . : <i>TSO007</i>
+Device type . . . . : <i>3390</i>
+Data class. . . . . : <i>LOAD</i>
+Organization  . . . : PO
+Record format . . . : U
+Record length . . . : 0
+Block size  . . . . : <i>32760</i>
+1st extent cylinders: 1
+Secondary cylinders : 5
+Data set name type  : LIBRARY</samp>
+</pre>
+
+    <p>The PDS can be allocated with the following attributes:</p>
+<pre>
+<samp>Data Set Name . . . : <i>USER</i>.ICU.EXP
+Management class. . : <i>**None**</i>
+Storage class . . . : <i>BASE</i>
+Volume serial . . . : <i>TSO007</i>
+Device type . . . . : <i>3390</i>
+Data class. . . . . : <i>**None**</i>
+Organization  . . . : PO
+Record format . . . : FB
+Record length . . . : 80
+Block size  . . . . : <i>3200</i>
+1st extent cylinders: 3
+Secondary cylinders : 3
+Data set name type  : PDS</samp>
+</pre>
+
+    <h3><a name="HowToBuildOS400" href="#HowToBuildOS400" id=
+    "HowToBuildOS400">How To Build And Install On The IBM i Family (IBM i, i5/OS OS/400)</a></h3>
+
+    <p>Before you start building ICU, ICU requires the following:</p>
+
+    <ul>
+      <li>QSHELL interpreter installed (install base option 30, operating system)
+      <!--li>QShell Utilities, PRPQ 5799-XEH (not required for V4R5)</li--></li>
+
+      <li>ILE C/C++ Compiler installed on the system
+
+      <li>The latest GNU facilities (You can get the GNU facilities 
+      from <a href=
+      "http://www.ibm.com/servers/enable/site/porting/iseries/overview/gnu_utilities.html">
+      http://www.ibm.com/servers/enable/site/porting/iseries/overview/gnu_utilities.html</a>).
+      Older versions may not work properly.</li>
+    </ul>
+
+    <p>The following describes how to setup and build ICU. For background
+    information, you should look at the <a href="#HowToBuildUNIX">UNIX build
+    instructions</a>.</p>
+
+    <ol>
+      <li>
+        Create target library. This library will be the target for the
+        resulting modules, programs and service programs. You will specify this
+        library on the OUTPUTDIR environment variable.
+<pre>
+<samp>CRTLIB LIB(<i>libraryname</i>)
+ADDENVVAR ENVVAR(OUTPUTDIR) VALUE('<i>libraryname</i>') REPLACE(*YES)   </samp>
+</pre>
+      </li>
+
+      <li>
+      Set up the following environment variables and job characteristics in your build process
+<pre>
+<samp>ADDENVVAR ENVVAR(MAKE) VALUE('/usr/bin/gmake') REPLACE(*YES)
+CHGJOB CCSID(37)</samp>
+</pre>
+
+      <li>Run <tt>'QSH'</tt></li>
+
+      <li>Run gunzip on the ICU source code compressed tar archive
+      (icu-<i>X</i>.<i>Y</i>.tgz).</li>
+
+      <li>Run <a href='as_is/os400/unpax-icu.sh'>unpax-icu.sh</a> on the tar file generated from the previous step.</li>
+
+      <li>Change your current directory to icu/source.</li>
+
+      <li>Run <tt>'./runConfigureICU IBMi'</tt>  (See <a href="#HowToConfigureICU">configuration
+      note</a> for details).</li></li>
+
+      <li>Run <tt>'gmake'</tt> to build ICU.</li>
+
+      <li>Run <tt>'gmake check QIBM_MULTI_THREADED=Y'</tt> to build and run the tests.
+      You can look at the <a href=
+      "http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/apis/concept4.htm">
+      iSeries Information Center</a> for more details regarding the running of multiple threads
+      on IBM i.</li>
+    </ol>
+
+      <!-- cross -->
+    <h3><a name="HowToCrossCompileICU" href="#HowToCrossCompileICU" id="HowToCrossCompileICU">How To Cross Compile ICU</a></h3>
+		<p>This section will explain how to build ICU on one platform, but to produce binaries intended to run on another. This is commonly known as a cross compile.</p>
+		<p>Normally, in the course of a build, ICU needs to run the tools that it builds in order to generate and package data and test-data.In a cross compilation setting, ICU is built on a different system from that which it eventually runs on. An example might be, if you are building for a small/headless system (such as an embedded device), or a system where you can't easily run the ICU command line tools (any non-UNIX-like system).</p>
+		<p>To reduce confusion, we will here refer to the "A" and the "B" system.System "A" is the actual system we will be running on- the only requirements on it is are it is able to build ICU from the command line targetting itself (with configure or runConfigureICU), and secondly, that it also contain the correct toolchain for compiling and linking for the resultant platform, referred to as the "B" system.</p>
+		<p>The autoconf docs use the term "build" for A, and "host" for B. More details at: <a href="http://www.gnu.org/software/autoconf/manual/html_node/Specifying-Names.html#Specifying-Names">http://www.gnu.org/software/autoconf/manual/html_node/Specifying-Names.html</a></p>
+		<p>Three initially-empty directories will be used in this example:</p>
+		<table summary="Three directories used in this example" class="docTable">
+			<tr>
+				<th align=left>/icu</th><td>a copy of the ICU source</td>
+			</tr>
+			<tr>
+				<th align=left>/buildA</th><td>an empty directory, it will contain ICU built for A<br>(MacOSX in this case)</td>
+			</tr>
+			<tr>
+				<th align=left>/buildB</th><td>an empty directory, it will contain ICU built for B<br>(HaikuOS in this case)</td>
+			</tr>
+		</table>
+		
+		<ol>
+		<li>Check out or unpack the ICU source code into the /icu directory.You will have the directories /icu/source, etc.</li>
+		<li>Build ICU in /buildA normally (using runConfigureICU or configure):
+<pre class="samp">cd /buildA
+sh /icu/source/runConfigureICU <strong>MacOSX</strong>
+gnumake
+</pre>
+		</li>
+		<li>Set PATH or other variables as needed, such as CPPFLAGS.</li>
+		<li>Build ICU in /buildB<br>
+			<div class="note"><b>Note:</b> "<code>--with-cross-build</code>" takes an absolute path.</div>
+<pre class="samp">cd /buildB
+sh /icu/source/configure --host=<strong>i586-pc-haiku</strong> --with-cross-build=<strong>/buildA</strong>
+gnumake</pre>
+		</li>
+		<li>Tests and testdata can be built with "gnumake tests".</li>
+	</ol>
+      <!-- end cross -->
+
+    <!-- end build environment -->
+
+    <h2><a name="HowToPackage" href="#HowToPackage" id="HowToPackage">How To
+    Package ICU</a></h2>
+
+    <p>There are many ways that a person can package ICU with their software
+    products. Usually only the libraries need to be considered for packaging.</p>
+
+    <p>On UNIX, you should use "<tt>gmake install</tt>" to make it easier to
+    develop and package ICU. The bin, lib and include directories are needed to
+    develop applications that use ICU. These directories will be created relative
+    to the "<tt>--prefix=</tt><i>dir</i>" configure option (See the <a href=
+    "#HowToBuildUNIX">UNIX build instructions</a>). When ICU is built on Windows,
+    a similar directory structure is built.</p>
+
+    <p>When changes have been made to the standard ICU distribution, it is
+    recommended that at least one of the following guidelines be followed for
+    special packaging.</p>
+
+    <ol>
+      <li>Add a suffix name to the library names. This can be done with the
+      --with-library-suffix configure option.</li>
+
+      <li>The installation script should install the ICU libraries into the
+      application's directory.</li>
+    </ol>
+
+    <p>Following these guidelines prevents other applications that use a standard
+    ICU distribution from conflicting with any libraries that you need. On
+    operating systems that do not have a standard C++ ABI (name mangling) for
+    compilers, it is recommended to do this special packaging anyway. More
+    details on customizing ICU are available in the <a href=
+    "http://userguide.icu-project.org/">User's Guide</a>. The <a href=
+    "#SourceCode">ICU Source Code Organization</a> section of this readme.html
+    gives a more complete description of the libraries.</p>
+
+    <table class="docTable" summary=
+    "ICU has several libraries for you to use.">
+      <caption>
+        Here is an example of libraries that are frequently packaged.
+      </caption>
+
+      <tr>
+        <th scope="col">Library Name</th>
+
+        <th scope="col">Windows Filename</th>
+
+        <th scope="col">Linux Filename</th>
+
+        <th scope="col">Comment</th>
+      </tr>
+
+      <tr>
+        <td>Data Library</td>
+
+        <td>icudt<i>XY</i>l.dll</td>
+
+        <td>libicudata.so.<i>XY</i>.<i>Z</i></td>
+
+        <td>Data required by the Common and I18n libraries. There are many ways
+        to package and <a href=
+        "http://userguide.icu-project.org/icudata">customize this
+        data</a>, but by default this is all you need.</td>
+      </tr>
+
+      <tr>
+        <td>Common Library</td>
+
+        <td>icuuc<i>XY</i>.dll</td>
+
+        <td>libicuuc.so.<i>XY</i>.<i>Z</i></td>
+
+        <td>Base library required by all other ICU libraries.</td>
+      </tr>
+
+      <tr>
+        <td>Internationalization (i18n) Library</td>
+
+        <td>icuin<i>XY</i>.dll</td>
+
+        <td>libicui18n.so.<i>XY</i>.<i>Z</i></td>
+
+        <td>A library that contains many locale based internationalization (i18n)
+        functions.</td>
+      </tr>
+
+      <tr>
+        <td>Layout Engine</td>
+
+        <td>icule<i>XY</i>.dll</td>
+
+        <td>libicule.so.<i>XY</i>.<i>Z</i></td>
+
+        <td>An optional engine for doing font layout.</td>
+      </tr>
+
+      <tr>
+        <td>Layout Extensions Engine</td>
+
+        <td>iculx<i>XY</i>.dll</td>
+
+        <td>libiculx.so.<i>XY</i>.<i>Z</i></td>
+
+        <td>An optional engine for doing font layout that uses parts of ICU.</td>
+      </tr>
+
+      <tr>
+        <td>ICU I/O (Unicode stdio) Library</td>
+
+        <td>icuio<i>XY</i>.dll</td>
+
+        <td>libicuio.so.<i>XY</i>.<i>Z</i></td>
+
+        <td>An optional library that provides a stdio like API with Unicode
+        support.</td>
+      </tr>
+
+      <tr>
+        <td>Tool Utility Library</td>
+
+        <td>icutu<i>XY</i>.dll</td>
+
+        <td>libicutu.so.<i>XY</i>.<i>Z</i></td>
+
+        <td>An internal library that contains internal APIs that are only used by
+        ICU's tools. If you do not use ICU's tools, you do not need this
+        library.</td>
+      </tr>
+    </table>
+
+    <p>Normally only the above ICU libraries need to be considered for packaging.
+    The versionless symbolic links to these libraries are only needed for easier
+    development. The <i>X</i>, <i>Y</i> and <i>Z</i> parts of the name are the
+    version numbers of ICU. For example, ICU 2.0.2 would have the name
+    libicuuc.so.20.2 for the common library. The exact format of the library
+    names can vary between platforms due to how each platform can handles library
+    versioning.</p>
+
+    <h2><a name="ImportantNotes" href="#ImportantNotes" id=
+    "ImportantNotes">Important Notes About Using ICU</a></h2>
+
+    <h3><a name="ImportantNotesMultithreaded" href="#ImportantNotesMultithreaded"
+    id="ImportantNotesMultithreaded">Using ICU in a Multithreaded
+    Environment</a></h3>
+
+    <p>Some versions of ICU require calling the <code>u_init()</code> function
+    from <code>uclean.h</code> to ensure that ICU is initialized properly. In
+    those ICU versions, <code>u_init()</code> must be called before ICU is used
+    from multiple threads. There is no harm in calling <code>u_init()</code> in a
+    single-threaded application, on a single-CPU machine, or in other cases where
+    <code>u_init()</code> is not required.</p>
+
+    <p>In addition to ensuring thread safety, <code>u_init()</code> also attempts
+    to load at least one ICU data file. Assuming that all data files are packaged
+    together (or are in the same folder in files mode), a failure code from
+    <code>u_init()</code> usually means that the data cannot be found. In this
+    case, the data may not be installed properly, or the application may have
+    failed to call <code>udata_setCommonData()</code> or
+    <code>u_setDataDirectory()</code> which specify to ICU where it can find its
+    data.</p>
+
+    <p>Since <code>u_init()</code> will load only one or two data files, it
+    cannot guarantee that all of the data that an application needs is available.
+    It cannot check for all data files because the set of files is customizable,
+    and some ICU services work without loading any data at all. An application
+    should always check for error codes when opening ICU service objects (using
+    <code>ucnv_open()</code>, <code>ucol_open()</code>, C++ constructors,
+    etc.).</p>
+
+    <h4>ICU 3.4 and later</h4>
+
+    <p>ICU 3.4 self-initializes properly for multi-threaded use. It achieves this
+    without performance penalty by hardcoding the core Unicode properties data,
+    at the cost of some flexibility. (For details see Jitterbug 4497.)</p>
+
+    <p><code>u_init()</code> can be used to check for data loading. It tries to
+    load the converter alias table (<code>cnvalias.icu</code>).</p>
+
+    <h4>ICU 2.6..3.2</h4>
+
+    <p>These ICU versions require a call to <code>u_init()</code> before
+    multi-threaded use. The services that are directly affected are those that
+    don't have a service object and need to be fast: normalization and character
+    properties.</p>
+
+    <p><code>u_init()</code> loads and initializes the data files for
+    normalization and character properties (<code>unorm.icu</code> and
+    <code>uprops.icu</code>) and can therefore also be used to check for data
+    loading.</p>
+
+    <h4>ICU 2.4 and earlier</h4>
+
+    <p>ICU 2.4 and earlier versions were not prepared for multithreaded use on
+    multi-CPU platforms where the CPUs implement weak memory coherency. These
+    CPUs include: Power4, Power5, Alpha, Itanium. <code>u_init()</code> was not
+    defined yet.</p>
+
+    <h4><a name="ImportantNotesHPUX" href="#ImportantNotesHPUX" id=
+    "ImportantNotesHPUX">Using ICU in a Multithreaded Environment on
+    HP-UX</a></h4>
+
+    <p>If you are building ICU with a newer aCC compiler and you are planning on
+    using the older &lt;iostream.h&gt; instead of the newer &lt;iostream&gt;, you
+    will need to use a special configure flag before building ICU. By default,
+    the aCC <a href="http://docs.hp.com/en/1405/options.htm#optioncap-AA">-AA</a>
+    flag is used on HP-UX when the compiler supports that option in order to make
+    ICU thread safe with RogueWave and other libraries using the 2.0 Standard C++
+    library. Your applications that use ICU will also need to use the <a href=
+    "http://docs.hp.com/en/1405/options.htm#optioncap-AA">-AA</a> compiler flag.
+    To turn off this behavior in ICU, you will need to use the --with-iostream=old
+    configure option when you first use runConfigureICU.</p>
+
+    <h4><a name="ImportantNotesSolaris" href="#ImportantNotesSolaris" id=
+    "ImportantNotesSolaris">Using ICU in a Multithreaded Environment on
+    Solaris</a></h4>
+
+    <h5>Linking on Solaris</h5>
+
+    <p>In order to avoid synchronization and threading issues, developers are
+    <strong>suggested</strong> to strictly follow the compiling and linking
+    guidelines for multithreaded applications, specified in the following
+    document from Sun Microsystems. Most notably, pay strict attention to the
+    following statements from Sun:</p>
+
+    <blockquote>
+      <p>To use libthread, specify -lthread before -lc on the ld command line, or
+      last on the cc command line.</p>
+
+      <p>To use libpthread, specify -lpthread before -lc on the ld command line,
+      or last on the cc command line.</p>
+    </blockquote>
+
+    <p>Failure to do this may cause spurious lock conflicts, recursive mutex
+    failure, and deadlock.</p>
+
+    <p>Source: "<i>Solaris Multithreaded Programming Guide, Compiling and
+    Debugging</i>", Sun Microsystems, Inc., Apr 2004<br />
+     <a href=
+    "http://docs.sun.com/app/docs/doc/816-5137/6mba5vpke?a=view">http://docs.sun.com/app/docs/doc/816-5137/6mba5vpke?a=view</a></p>
+
+    <h3><a name="ImportantNotesWindows" href="#ImportantNotesWindows" id=
+    "ImportantNotesWindows">Windows Platform</a></h3>
+
+    <p>If you are building on the Win32 platform, it is important that you
+    understand a few of the following build details.</p>
+
+    <h4>DLL directories and the PATH setting</h4>
+
+    <p>As delivered, the International Components for Unicode build as several
+    DLLs, which are placed in the "<i>&lt;ICU&gt;</i>\bin" directory. You must
+    add this directory to the PATH environment variable in your system, or any
+    executables you build will not be able to access International Components for
+    Unicode libraries. Alternatively, you can copy the DLL files into a directory
+    already in your PATH, but we do not recommend this. You can wind up with
+    multiple copies of the DLL and wind up using the wrong one.</p>
+
+    <h4><a name="ImportantNotesWindowsPath" id=
+    "ImportantNotesWindowsPath">Changing your PATH</a></h4>
+
+    <p><strong>Windows 2000/XP</strong>: Use the System Icon in the Control
+    Panel. Pick the "Advanced" tab. Select the "Environment Variables..."
+    button. Select the variable PATH in the lower box, and select the lower
+    "Edit..." button. In the "Variable Value" box, append the string
+    ";<i>&lt;ICU&gt;</i>\bin" to the end of the path string. If there is
+    nothing there, just type in "<i>&lt;ICU&gt;</i>\bin". Click the Set button,
+    then the OK button.</p>
+
+    <p>Note: When packaging a Windows application for distribution and
+    installation on user systems, copies of the ICU DLLs should be included with
+    the application, and installed for exclusive use by the application. This is
+    the only way to insure that your application is running with the same version
+    of ICU, built with exactly the same options, that you developed and tested
+    with. Refer to Microsoft's guidelines on the usage of DLLs, or search for the
+    phrase "DLL hell" on <a href=
+    "http://msdn.microsoft.com/">msdn.microsoft.com</a>.</p>
+
+    <h3><a name="ImportantNotesUNIX" href="#ImportantNotesUNIX" id=
+    "ImportantNotesUNIX">UNIX Type Platform</a></h3>
+
+    <p>If you are building on a UNIX platform, and if you are installing ICU in a
+    non-standard location, you may need to add the location of your ICU libraries
+    to your <strong>LD_LIBRARY_PATH</strong> or <strong>LIBPATH</strong>
+    environment variable (or the equivalent runtime library path environment
+    variable for your system). The ICU libraries may not link or load properly
+    without doing this.</p>
+
+    <p>Note that if you do not want to have to set this variable, you may instead
+    use the --enable-rpath option at configuration time. This option will
+    instruct the linker to always look for the libraries where they are
+    installed. You will need to use the appropriate linker options when linking
+    your own applications and libraries against ICU, too. Please refer to your
+    system's linker manual for information about runtime paths. The use of rpath
+    also means that when building a new version of ICU you should not have an
+    older version installed in the same place as the new version's installation
+    directory, as the older libraries will used during the build, instead of the
+    new ones, likely leading to an incorrectly build ICU. This is the proper
+    behavior of rpath.</p>
+
+    <h2><a name="PlatformDependencies" href="#PlatformDependencies" id=
+    "PlatformDependencies">Platform Dependencies</a></h2>
+
+    <h3><a name="PlatformDependenciesNew" href="#PlatformDependenciesNew" id=
+    "PlatformDependenciesNew">Porting To A New Platform</a></h3>
+
+    <p>If you are using ICU's Makefiles to build ICU on a new platform, there are
+    a few places where you will need to add or modify some files. If you need
+    more help, you can always ask the <a href=
+    "http://site.icu-project.org/contacts">icu-support mailing list</a>. Once
+    you have finished porting ICU to a new platform, it is recommended that you
+    contribute your changes back to ICU via the icu-support mailing list. This
+    will make it easier for everyone to benefit from your work.</p>
+
+    <h4>Data For a New Platform</h4>
+
+    <p>For some people, it may not be necessary for completely build ICU. Most of
+    the makefiles and build targets are for tools that are used for building
+    ICU's data, and an application's data (when an application uses ICU resource
+    bundles for its data).</p>
+
+    <p>Data files can be built on a different platform when both platforms share
+    the same endianness and the same charset family. This assertion does not
+    include platform dependent DLLs/shared/static libraries. For details see the
+    User Guide <a href="http://userguide.icu-project.org/icudata">ICU
+    Data</a> chapter.</p>
+
+    <p>ICU 3.6 removes the requirement that ICU be completely built in the native
+    operating environment. It adds the icupkg tool which can be run on any
+    platform to turn binary ICU data files from any one of the three formats into
+    any one of the other data formats. This allows a application to use ICU data
+    built anywhere to be used for any other target platform.</p>
+
+    <p><strong>WARNING!</strong> Building ICU without running the tests is not
+    recommended. The tests verify that ICU is safe to use. It is recommended that
+    you try to completely port and test ICU before using the libraries for your
+    own application.</p>
+
+    <h4>Adapting Makefiles For a New Platform</h4>
+
+    <p>Try to follow the build steps from the <a href="#HowToBuildUNIX">UNIX</a>
+    build instructions. If the configure script fails, then you will need to
+    modify some files. Here are the usual steps for porting to a new
+    platform:<br />
+    </p>
+
+    <ol>
+      <li>Create an mh file in icu/source/config/. You can use mh-linux or a
+      similar mh file as your base configuration.</li>
+
+      <li>Modify icu/source/aclocal.m4 to recognize your platform's mh file.</li>
+
+      <li>Modify icu/source/configure.in to properly set your <b>platform</b> C
+      Macro define.</li>
+
+      <li>Run <a href="http://www.gnu.org/software/autoconf/">autoconf</a> in
+      icu/source/ without any options. The autoconf tool is standard on most
+      Linux systems.</li>
+
+      <li>If you have any optimization options that you want to normally use, you
+      can modify icu/source/runConfigureICU to specify those options for your
+      platform.</li>
+
+      <li>Build and test ICU on your platform. It is very important that you run
+      the tests. If you don't run the tests, there is no guarentee that you have
+      properly ported ICU.</li>
+    </ol>
+
+    <h3><a name="PlatformDependenciesImpl" href="#PlatformDependenciesImpl" id=
+    "PlatformDependenciesImpl">Platform Dependent Implementations</a></h3>
+
+    <p>The platform dependencies have been mostly isolated into the following
+    files in the common library. This information can be useful if you are
+    porting ICU to a new platform.</p>
+
+    <ul>
+      <li>
+        <strong>unicode/platform.h.in</strong> (autoconf'ed platforms)<br />
+         <strong>unicode/p<i>XXXX</i>.h</strong> (others: pwin32.h, ppalmos.h,
+        ..): Platform-dependent typedefs and defines:<br />
+        <br />
+         
+
+        <ul>
+          <li>Generic types like UBool, int8_t, int16_t, int32_t, int64_t,
+          uint64_t etc.</li>
+
+          <li>U_EXPORT and U_IMPORT for specifying dynamic library import and
+          export</li>
+
+          <li>&lt;iostream&gt; usability</li>
+
+          <li>Thread safety usability</li>
+        </ul>
+        <br />
+      </li>
+
+      <li>
+        <strong>unicode/putil.h, putil.c</strong>: platform-dependent
+        implementations of various functions that are platform dependent:<br />
+        <br />
+         
+
+        <ul>
+          <li>uprv_isNaN, uprv_isInfinite, uprv_getNaN and uprv_getInfinity for
+          handling special floating point values.</li>
+
+          <li>uprv_tzset, uprv_timezone, uprv_tzname and time for getting
+          platform specific time and time zone information.</li>
+
+          <li>u_getDataDirectory for getting the default data directory.</li>
+
+          <li>uprv_getDefaultLocaleID for getting the default locale
+          setting.</li>
+
+          <li>uprv_getDefaultCodepage for getting the default codepage
+          encoding.</li>
+        </ul>
+        <br />
+      </li>
+
+      <li>
+        <strong>umutex.h, umutex.c</strong>: Code for doing synchronization in
+        multithreaded applications. If you wish to use International Components
+        for Unicode in a multithreaded application, you must provide a
+        synchronization primitive that the classes can use to protect their
+        global data against simultaneous modifications. We already supply working
+        implementations for many platforms that ICU builds on.<br />
+        <br />
+      </li>
+
+      <li><strong>umapfile.h, umapfile.c</strong>: functions for mapping or
+      otherwise reading or loading files into memory. All access by ICU to data
+      from files makes use of these functions.<br />
+      <br />
+      </li>
+
+      <li>Using platform specific #ifdef macros are highly discouraged outside of
+      the scope of these files. When the source code gets updated in the future,
+      these #ifdef's can cause testing problems for your platform.</li>
+    </ul>
+    <hr />
+
+    <p>Copyright &copy; 1997-2010 International Business Machines Corporation and
+    others. All Rights Reserved.<br />
+     IBM Globalization Center of Competency - San Jos&eacute;<br />
+     4400 North First Street<br />
+     San Jos&eacute;, CA 95134<br />
+     USA</p>
+  </body>
+</html>
+
diff --git a/icu/source/Doxyfile.in b/icu/source/Doxyfile.in
new file mode 100644
index 0000000..771b993
--- /dev/null
+++ b/icu/source/Doxyfile.in
@@ -0,0 +1,233 @@
+# Doxyfile 1.3.7
+#  ********************************************************************
+#  * COPYRIGHT:
+#  * Copyright (c) 2004-2010, International Business Machines Corporation
+#  * and others. All Rights Reserved.
+#  ********************************************************************
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = "ICU @VERSION@"
+PROJECT_NUMBER         = @VERSION@
+OUTPUT_DIRECTORY       = doc
+CREATE_SUBDIRS         = NO
+OUTPUT_LANGUAGE        = English
+#USE_WINDOWS_ENCODING   = YES
+DOXYFILE_ENCODING	= UTF-8
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = 
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = 
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = YES
+MULTILINE_CPP_IS_BRIEF = NO
+#DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = YES
+TAB_SIZE               = 8
+ALIASES                = "memo=\par Note:\n" \
+                         "draft=\xrefitem draft \"Draft\" \"Draft List\"  This API may be changed in the future versions and was introduced in" \
+                         "stable=\xrefitem stable \"Stable\" \"Stable List\"" \
+                         "deprecated=\xrefitem deprecated \"Deprecated\" \"Deprecated List\"" \
+                         "obsolete=\xrefitem obsolete \"Obsolete\" \"Obsolete List\"" \
+                         "system=\xrefitem system \"System\" \"System List\" \n Do not use unless you know what you are doing." \
+                         "internal=\xrefitem internal \"Internal\"  \"Internal List\"  Do not use. This API is for internal use only." 
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = NO
+EXTRACT_PRIVATE        = NO
+EXTRACT_STATIC         = NO
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = YES
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+
+# docset
+GENERATE_DOCSET        = NO
+DOCSET_FEEDNAME        = "ICU @VERSION@"
+DOCSET_BUNDLE_ID       = org.icu-project.icu4c
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = ./common/unicode/platform.h @srcdir@/common/unicode @srcdir@/i18n/unicode @srcdir@/io/unicode @srcdir@/layout/LEFontInstance.h @srcdir@/layout/LEGlyphStorage.h @srcdir@/layout/LELanguages.h @srcdir@/layout/LEScripts.h @srcdir@/layout/LESwaps.h @srcdir@/layout/LETypes.h @srcdir@/layout/LayoutEngine.h @srcdir@/layoutex/layout
+FILE_PATTERNS          = *.h
+RECURSIVE              = NO
+EXCLUDE                = @srcdir@/common/unicode/urename.h @srcdir@/common/unicode/udraft.h @srcdir@/common/unicode/udeprctd.h @srcdir@/common/unicode/uobslete.h @srcdir@/common/unicode/ppalmos.h  
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = config*.h
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = 
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = YES
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = YES
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO 
+PERLMOD_LATEX          = YES
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = YES
+EXPAND_ONLY_PREDEF     = YES
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = U_EXPORT2= U_STABLE= U_DRAFT= U_INTERNAL= U_SYSTEM= U_DEPRECATED= U_OBSOLETE= U_CALLCONV= U_CDECL_BEGIN= U_CDECL_END=  U_NO_THROW= U_NAMESPACE_BEGIN= U_NAMESPACE_END= 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       =  "@builddir@/doc/html/icudocs.tag"
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = NO
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+CALLER_GRAPH		= NO
+GRAPHICAL_HIERARCHY    = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+#DOT_FONTNAME	       = FreeSans
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 0
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = YES
diff --git a/icu/source/Makefile.in b/icu/source/Makefile.in
new file mode 100644
index 0000000..a51ce32
--- /dev/null
+++ b/icu/source/Makefile.in
@@ -0,0 +1,267 @@
+#******************************************************************************
+#
+#   Copyright (C) 1998-2010, International Business Machines
+#   Corporation and others.  All Rights Reserved.
+#
+#******************************************************************************
+## Top-level Makefile.in for ICU
+## Stephen F. Booth
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+top_builddir = .
+
+include $(top_builddir)/icudefs.mk
+
+docdir = $(datadir)/doc
+docsubdir = $(PACKAGE)$(ICULIBDASHSUFFIX)/html
+docsubsrchdir = $(docsubdir)/search
+docfilesdir = doc/html
+docfiles = $(docfilesdir)/*.gif $(docfilesdir)/*.png $(docfilesdir)/*.html $(docfilesdir)/*.css $(docfilesdir)/*.tag $(docfilesdir)/installdox
+docsrchdir = $(docfilesdir)/search
+docsrchfiles = $(docsrchdir)/*
+
+##
+
+## Build directory information
+subdir = .
+
+#AUTOCONF = @AUTOCONF@
+
+## Optional directory setup
+@LAYOUT_TRUE@LAYOUT = layout layoutex
+@ICUIO_TRUE@ICUIO = io
+@EXTRAS_TRUE@EXTRA = extra
+@TESTS_TRUE@TEST = test
+@SAMPLES_TRUE@SAMPLE = samples
+
+DOXYGEN = @DOXYGEN@
+DOCZIP = icu-docs.zip
+
+## Files to remove for 'make clean'
+CLEANFILES = *~
+
+## Files built (autoconfed) and installed
+INSTALLED_BUILT_FILES = $(top_builddir)/config/Makefile.inc $(top_builddir)/config/pkgdata.inc $(top_builddir)/config/icu-config @platform_make_fragment@ $(EXTRA_DATA:%=$(DESTDIR)$(pkglibdir)/%)
+
+## Files built (autoconfed) but not installed
+LOCAL_BUILT_FILES = icudefs.mk config/icucross.mk
+
+DOCDIRS = common i18n
+SUBDIRS =  stubdata common i18n $(LAYOUT) tools data $(ICUIO) $(EXTRA) $(SAMPLE) $(TEST)
+
+SECTION = 1
+
+MANX_FILES = config/icu-config.$(SECTION)
+
+ALL_MAN_FILES = $(MANX_FILES)
+
+## Extra files to install [nothing at present]
+EXTRA_DATA =
+
+## List of phony targets
+.PHONY : all all-local all-recursive install install-local install-udata install-udata-files install-udata-dlls		\
+install-recursive clean clean-local clean-recursive distclean		\
+distclean-local distclean-recursive doc dist dist-local dist-recursive	\
+check check-local check-recursive clean-recursive-with-twist install-icu \
+doc install-doc tests icu4j-data icu4j-data-install update-windows-makefiles
+
+## Clear suffix list
+.SUFFIXES :
+
+## List of standard targets
+all: all-local all-recursive
+install: install-recursive install-local
+clean: clean-recursive-with-twist clean-local
+distclean : distclean-recursive distclean-local
+dist: dist-recursive dist-local
+check: all check-recursive
+check-recursive: all
+
+ifeq ($(DOXYGEN),)
+doc:
+	@echo you need Doxygen to generate documentation. Doxygen can be found on the Web
+	@echo at http://www.doxygen.org/
+else
+doc: doc/html/index.html
+
+doc/html/index.html: Doxyfile $(wildcard ./common/unicode/platform.h $(srcdir)/common/unicode/*.h $(srcdir)/i18n/unicode/*.h $(srcdir)/layout/unicode/*.h $(srcdir)/io/unicode/*.h)
+	$(DOXYGEN)
+
+Doxyfile: $(srcdir)/Doxyfile.in
+	CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(DOCZIP): doc
+	-$(RMV) $(DOCZIP)
+	( cd doc/html ; zip -r ../../$(DOCZIP) * )
+endif
+
+LOCAL_SUBDIRS = $(SUBDIRS)
+CLEAN_FIRST_SUBDIRS = tools
+
+$(LIBDIR) $(BINDIR):
+	-$(MKINSTALLDIRS) $@
+
+## Recursive targets
+all-recursive install-recursive clean-recursive distclean-recursive dist-recursive check-recursive: $(LIBDIR) $(BINDIR)
+	@dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(LOCAL_SUBDIRS)'; for subdir in $$list; do \
+	  echo "$(MAKE)[$(MAKELEVEL)]: Making \`$$target' in \`$$subdir'"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-local"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  (cd $$subdir && $(MAKE) RECURSIVE=YES $$local_target) || exit; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) "$$target-local" || exit; \
+	fi
+
+clean-recursive-with-twist:
+	$(MAKE) clean-recursive LOCAL_SUBDIRS='$(CLEAN_FIRST_SUBDIRS) $(filter-out $(CLEAN_FIRST_SUBDIRS),$(LOCAL_SUBDIRS))'
+
+all-local: $(srcdir)/configure $(LOCAL_BUILT_FILES) $(INSTALLED_BUILT_FILES)
+
+install-local: install-icu install-manx
+
+install-icu: $(INSTALLED_BUILT_FILES)
+	@$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/config
+	@$(MKINSTALLDIRS) $(DESTDIR)$(pkglibdir)
+	@$(MKINSTALLDIRS) $(DESTDIR)$(bindir)
+	@$(MKINSTALLDIRS) $(DESTDIR)$(sbindir)
+	$(INSTALL_DATA) @platform_make_fragment@ $(DESTDIR)$(pkgdatadir)/config/@platform_make_fragment_name@
+	$(INSTALL_SCRIPT) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(pkgdatadir)/mkinstalldirs
+	$(INSTALL_SCRIPT) $(top_srcdir)/install-sh $(DESTDIR)$(pkgdatadir)/install-sh
+	$(INSTALL_DATA) $(top_srcdir)/../license.html $(DESTDIR)$(pkgdatadir)/license.html
+	$(INSTALL_SCRIPT) $(top_builddir)/config/icu-config $(DESTDIR)$(bindir)/icu-config
+	$(INSTALL_DATA) $(top_builddir)/config/Makefile.inc $(DESTDIR)$(pkglibdir)/Makefile.inc
+	$(INSTALL_DATA) $(top_builddir)/config/pkgdata.inc $(DESTDIR)$(pkglibdir)/pkgdata.inc
+	cd $(DESTDIR)$(pkglibdir)/..; \
+	    $(RM) current && ln -s $(VERSION) current; \
+	    $(RM) Makefile.inc && ln -s current/Makefile.inc Makefile.inc; \
+	    $(RM) pkgdata.inc && ln -s current/pkgdata.inc pkgdata.inc
+
+ifeq ($(DOXYGEN),)
+install-doc:
+else
+install-doc: doc
+	$(RM) -r $(DESTDIR)$(docdir)/$(docsubdir)
+	$(MKINSTALLDIRS) $(DESTDIR)$(docdir)/$(docsubsrchdir)
+	$(INSTALL_DATA) $(docfiles) $(DESTDIR)$(docdir)/$(docsubdir)
+	$(INSTALL_DATA) $(docsrchfiles) $(DESTDIR)$(docdir)/$(docsubsrchdir)
+endif
+
+$(DESTDIR)$(pkglibdir)/%: $(top_srcdir)/../data/%
+	$(INSTALL_DATA) $< $@
+
+# Build the tests, but don't run them.
+tests: all
+	$(MAKE) -C $(top_builddir)/test
+
+dist-local:
+
+clean-local:
+	test -z "$(CLEANFILES)" || $(RMV) $(CLEANFILES)
+	$(RMV) Doxyfile doc $(DOCZIP)
+
+distclean-local: clean-local
+	$(RMV) $(top_builddir)/config/Makefile.inc $(top_builddir)/config/pkgdata.inc $(top_builddir)/config/icu-config
+	$(RMV) config.cache config.log config.status $(top_builddir)/config/icucross.mk autom4te.cache
+	$(RMV) Makefile config/Makefile icudefs.mk $(LIBDIR) $(BINDIR)
+
+check-local: $(top_builddir)/config/icu-config $(top_builddir)/config/Makefile.inc $(top_builddir)/config/pkgdata.inc
+	@echo verifying that icu-config --selfcheck can operate
+	@test "passed" = "$(shell $(top_builddir)/config/icu-config --selfcheck 2>&1)" || (echo "FAIL: icu-config could not run properly." ; exit 1)
+	@echo verifying that $(MAKE) -f Makefile.inc selfcheck can operate
+	@test "passed" = "$(shell $(MAKE) --no-print-directory -f $(top_builddir)/config/Makefile.inc SELFCHECK=1 selfcheck)" || (echo "FAIL: Makefile.inc could not run properly." ; exit 1 )
+	@echo "PASS: config selfcheck OK"
+
+#$(srcdir)/configure : $(srcdir)/configure.in $(top_srcdir)/aclocal.m4
+#	cd $(srcdir) && $(AUTOCONF)
+
+icudefs.mk: $(srcdir)/icudefs.mk.in  $(top_builddir)/config.status
+	cd $(top_builddir) \
+		&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+config/icucross.mk: $(top_builddir)/icudefs.mk  $(top_builddir)/Makefile
+	@echo rebuilding $@
+	@(echo "CROSS_ICU_VERSION=$(VERSION)" ;\
+	  echo "TOOLEXEEXT=$(EXEEXT)" \
+	   ) > $@
+	@(echo 'TOOLBINDIR=$$(cross_buildroot)/bin' ;\
+	  echo 'TOOLLIBDIR=$$(cross_buildroot)/lib' ;\
+	  echo "INVOKE=$(LDLIBRARYPATH_ENVVAR)=$(LIBRARY_PATH_PREFIX)"'$$(TOOLLIBDIR):$$(cross_buildroot)/stubdata:$$(cross_buildroot)/tools/ctestfw:$$$$'"$(LDLIBRARYPATH_ENVVAR)" ;\
+	  echo "PKGDATA_INVOKE=$(LDLIBRARYPATH_ENVVAR)=$(LIBRARY_PATH_PREFIX)"'$$(cross_buildroot)/stubdata:$$(cross_buildroot)/tools/ctestfw:$$(TOOLLIBDIR):$$$$'"$(LDLIBRARYPATH_ENVVAR) "'$$'"(PKGDATA_INVOKE_OPTS)" ;\
+	  echo ) >> $@
+
+Makefile: $(srcdir)/Makefile.in icudefs.mk $(top_builddir)/config.status
+	cd $(top_builddir) \
+		&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(top_builddir)/config/Makefile.inc: $(srcdir)/config/Makefile.inc.in  $(top_builddir)/config.status
+	cd $(top_builddir) \
+		&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(top_builddir)/config/pkgdata.inc: icudefs.mk $(top_builddir)/config/pkgdataMakefile
+	cd $(top_builddir)/config; \
+		$(MAKE) -f pkgdataMakefile
+
+$(top_builddir)/config/pkgdataMakefile:
+	cd $(top_builddir) \
+		&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(top_builddir)/config/icu-config: $(top_builddir)/Makefile $(top_srcdir)/config/icu-config-top $(top_srcdir)/config/icu-config-bottom $(top_builddir)/config/Makefile.inc @platform_make_fragment@ $(top_srcdir)/config/make2sh.sed
+	-$(RMV) $@
+	$(INSTALL_SCRIPT) $(top_srcdir)/config/icu-config-top $@
+	chmod u+w $@
+	@echo "# Following from @platform_make_fragment@" >> $@
+	sed -f $(top_srcdir)/config/make2sh.sed < $(top_builddir)/config/Makefile.inc | grep -v '#M#' | uniq >> $@
+	sed -f $(top_srcdir)/config/make2sh.sed < @platform_make_fragment@ | grep -v '#M#' | uniq >> $@
+	cat $(top_srcdir)/config/icu-config-bottom >> $@
+	echo "# Rebuilt on "`date` >> $@
+	chmod u-w $@
+
+config.status: $(srcdir)/configure $(srcdir)/common/unicode/uvernum.h
+	@echo
+	@echo
+	@echo "*** config.status has become stale ***"
+	@echo "   'configure' and/or 'uvernum.h' have changed, please"
+	@echo "  do 'runConfigureICU' (or 'configure') again, as per"
+	@echo "  the readme.html."
+	@echo
+	@echo
+	exit 1
+
+
+install-manx: $(MANX_FILES)
+	$(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man$(SECTION)
+	$(INSTALL_DATA) $? $(DESTDIR)$(mandir)/man$(SECTION)
+
+config/%.$(SECTION): $(srcdir)/config/%.$(SECTION).in
+	cd $(top_builddir) \
+	 && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+icu4j-data-install icu4j-data: all tests
+	@echo ICU4J_ROOT=$(ICU4J_ROOT)
+	@$(MAKE) -C test/testdata $@
+	@$(MAKE) -C data $@
+
+WINDOWS_UPDATEFILES=$(srcdir)/data/makedata.mak $(shell find $(srcdir) -name '*.vcproj')
+
+WINDOWS_UPDATEFILES_SED=config/windows-update.sed
+
+update-windows-makefiles: config.status
+	@echo Updating Windows Makefiles for ICU $(VERSION)
+	CONFIG_FILES=$(WINDOWS_UPDATEFILES_SED) CONFIG_HEADERS= $(SHELL) ./config.status
+	@for file in $(WINDOWS_UPDATEFILES); do \
+	  echo "Updating $$file"; \
+	  mv "$${file}" "$${file}.bak" && \
+	  sed -f $(WINDOWS_UPDATEFILES_SED) < "$${file}.bak" > "$${file}" && \
+	  rm "$${file}.bak"; \
+	done;
+	$(RMV) $(WINDOWS_UPDATEFILES_SED)
+	@echo Please check over the changes carefully before checking them in.
diff --git a/icu/source/aclocal.m4 b/icu/source/aclocal.m4
new file mode 100644
index 0000000..ef5bf83
--- /dev/null
+++ b/icu/source/aclocal.m4
@@ -0,0 +1,486 @@
+# aclocal.m4 for ICU
+# Copyright (c) 1999-2010, International Business Machines Corporation and
+# others. All Rights Reserved.
+# Stephen F. Booth
+
+# @TOP@
+
+# ICU_CHECK_MH_FRAG
+AC_DEFUN(ICU_CHECK_MH_FRAG, [
+	AC_CACHE_CHECK(
+		[which Makefile fragment to use for ${host}],
+		[icu_cv_host_frag],
+		[
+case "${host}" in
+*-*-solaris*)
+	if test "$GCC" = yes; then	
+		icu_cv_host_frag=mh-solaris-gcc
+	else
+		icu_cv_host_frag=mh-solaris
+	fi ;;
+alpha*-*-linux-gnu)
+	if test "$GCC" = yes; then
+		icu_cv_host_frag=mh-alpha-linux-gcc
+	else
+		icu_cv_host_frag=mh-alpha-linux-cc
+	fi ;;
+powerpc*-*-linux*)
+	if test "$GCC" = yes; then
+		icu_cv_host_frag=mh-linux
+	else
+		icu_cv_host_frag=mh-linux-va
+	fi ;;
+*-*-linux*|*-pc-gnu) icu_cv_host_frag=mh-linux ;;
+*-*-cygwin|*-*-mingw32)
+	if test "$GCC" = yes; then
+		AC_TRY_COMPILE([
+#ifndef __MINGW32__
+#error This is not MinGW
+#endif], [], icu_cv_host_frag=mh-mingw, icu_cv_host_frag=mh-cygwin)
+	else
+		icu_cv_host_frag=mh-cygwin-msvc
+	fi ;;
+*-*-*bsd*|*-*-dragonfly*) 	icu_cv_host_frag=mh-bsd-gcc ;;
+*-*-aix*)
+	if test "$GCC" = yes; then
+		icu_cv_host_frag=mh-aix-gcc
+	else
+		icu_cv_host_frag=mh-aix-va
+	fi ;;
+*-*-hpux*)
+	if test "$GCC" = yes; then
+		icu_cv_host_frag=mh-hpux-gcc
+	else
+		case "$CXX" in
+		*aCC)    icu_cv_host_frag=mh-hpux-acc ;;
+		esac
+	fi ;;
+*-*ibm-openedition*|*-*-os390*)	icu_cv_host_frag=mh-os390 ;;
+*-*-os400*)	icu_cv_host_frag=mh-os400 ;;
+*-apple-rhapsody*)	icu_cv_host_frag=mh-darwin ;;
+*-apple-darwin*)	icu_cv_host_frag=mh-darwin ;;
+*-*-beos|*-*-haiku)	icu_cv_host_frag=mh-beos ;;
+*-*-irix*)	icu_cv_host_frag=mh-irix ;;
+*-dec-osf*) icu_cv_host_frag=mh-alpha-osf ;;
+*-*-nto*)	icu_cv_host_frag=mh-qnx ;;
+*-ncr-*)	icu_cv_host_frag=mh-mpras ;;
+*) 		icu_cv_host_frag=mh-unknown ;;
+esac
+		]
+	)
+])
+
+# ICU_CONDITIONAL - similar example taken from Automake 1.4
+AC_DEFUN(ICU_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+if $2; then
+  $1_TRUE=
+else
+  $1_TRUE='#'
+fi])
+
+# ICU_PROG_LINK - Make sure that the linker is usable
+AC_DEFUN(ICU_PROG_LINK,
+[
+case "${host}" in
+    *-*-cygwin*|*-*-mingw*)
+        if test "$GCC" != yes && test -n "`link --version 2>&1 | grep 'GNU coreutils'`"; then
+            AC_MSG_ERROR([link.exe is not a valid linker. Your PATH is incorrect.
+                  Please follow the directions in ICU's readme.])
+        fi;;
+    *);;
+esac])
+
+# AC_SEARCH_LIBS_FIRST(FUNCTION, SEARCH-LIBS [, ACTION-IF-FOUND
+#            [, ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]])
+# Search for a library defining FUNC, then see if it's not already available.
+
+AC_DEFUN(AC_SEARCH_LIBS_FIRST,
+[AC_PREREQ([2.13])
+AC_CACHE_CHECK([for library containing $1], [ac_cv_search_$1],
+[ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_$1="no"
+for i in $2; do
+LIBS="-l$i $5 $ac_func_search_save_LIBS"
+AC_TRY_LINK_FUNC([$1],
+[ac_cv_search_$1="-l$i"
+break])
+done
+if test "$ac_cv_search_$1" = "no"; then
+AC_TRY_LINK_FUNC([$1], [ac_cv_search_$1="none required"])
+fi
+LIBS="$ac_func_search_save_LIBS"])
+if test "$ac_cv_search_$1" != "no"; then
+  test "$ac_cv_search_$1" = "none required" || LIBS="$ac_cv_search_$1 $LIBS"
+  $3
+else :
+  $4
+fi])
+
+
+
+# Check if we can build and use 64-bit libraries
+AC_DEFUN(AC_CHECK_64BIT_LIBS,
+[
+    BITS_REQ=nochange
+    ENABLE_64BIT_LIBS=unknown
+    ## revisit this for cross-compile.
+    
+    AC_ARG_ENABLE(64bit-libs,
+        [  --enable-64bit-libs     (deprecated, use --with-library-bits) build 64-bit libraries [default= platform default]],
+        [echo "note, use --with-library-bits instead of --*-64bit-libs"
+         case "${enableval}" in
+            no|false|32) with_library_bits=32;  ;;
+            yes|true|64) with_library_bits=64else32 ;;
+            nochange) with_library_bits=nochange; ;;
+            *) AC_MSG_ERROR(bad value ${enableval} for '--*-64bit-libs') ;;
+            esac]    )
+    
+
+    AC_ARG_WITH(library-bits,
+        [  --with-library-bits=bits specify how many bits to use for the library (32, 64, 64else32, nochange) [default=nochange]],
+        [case "${withval}" in
+            ""|nochange) BITS_REQ=$withval ;;
+            32|64|64else32) BITS_REQ=$withval ;;
+            *) AC_MSG_ERROR(bad value ${withval} for --with-library-bits) ;;
+            esac])
+        
+    # don't use these for cross compiling
+    if test "$cross_compiling" = "yes" -a "${BITS_REQ}" != "nochange"; then
+        AC_MSG_ERROR([Don't specify bitness when cross compiling. See readme.html for help with cross compilation., and set compiler options manually.])
+    fi
+    AC_CHECK_SIZEOF([void *])
+    AC_MSG_CHECKING([whether runnable 64 bit binaries are built by default])
+    case $ac_cv_sizeof_void_p in
+        8) DEFAULT_64BIT=yes ;;
+        4) DEFAULT_64BIT=no ;;
+        *) DEFAULT_64BIT=unknown
+    esac
+    BITS_GOT=unknown
+    
+    # 'OK' here means, we can exit any further checking, everything's copa
+    BITS_OK=yes
+
+    # do we need to check for buildable/runnable 32 or 64 bit?
+    BITS_CHECK_32=no
+    BITS_CHECK_64=no
+    
+    # later, can we run the 32/64 bit binaries so made?
+    BITS_RUN_32=no
+    BITS_RUN_64=no
+    
+    if test "$DEFAULT_64BIT" = "yes"; then
+        # we get 64 bits by default.
+        BITS_GOT=64
+        case "$BITS_REQ" in
+            32) 
+                # need to look for 32 bit support. 
+                BITS_CHECK_32=yes
+                # not copa.
+                BITS_OK=no;;
+            # everyone else is happy.
+            nochange) ;;
+            *) ;;
+        esac
+    elif test "$DEFAULT_64BIT" = "no"; then
+        # not 64 bit by default.
+        BITS_GOT=32
+        case "$BITS_REQ" in
+            64|64else32)
+                BITS_CHECK_64=yes
+                #BITS_CHECK_32=yes
+                BITS_OK=no;;
+            nochange) ;;
+            *) ;;
+        esac
+    elif test "$DEFAULT_64BIT" = "unknown"; then
+        # cross compiling.
+        BITS_GOT=unknown
+        case "$BITS_REQ" in
+            64|64else32) BITS_OK=no
+            BITS_CHECK_32=yes
+            BITS_CHECK_64=yes ;;
+            32) BITS_OK=no;;
+            nochange) ;;
+            *) ;;
+        esac
+    fi
+            
+    AC_MSG_RESULT($DEFAULT_64BIT);
+
+    if test "$BITS_OK" != "yes"; then
+        # not copa. back these up.
+        CFLAGS_OLD="${CFLAGS}"
+        CXXFLAGS_OLD="${CXXFLAGS}"
+        LDFLAGS_OLD="${LDFLAGS}"
+        ARFLAGS_OLD="${ARFLAGS}"        
+        
+        CFLAGS_32="${CFLAGS}"
+        CXXFLAGS_32="${CXXFLAGS}"
+        LDFLAGS_32="${LDFLAGS}"
+        ARFLAGS_32="${ARFLAGS}"        
+        
+        CFLAGS_64="${CFLAGS}"
+        CXXFLAGS_64="${CXXFLAGS}"
+        LDFLAGS_64="${LDFLAGS}"
+        ARFLAGS_64="${ARFLAGS}"        
+        
+        CAN_BUILD_64=unknown
+        CAN_BUILD_32=unknown
+        # These results can't be cached because is sets compiler flags.
+        if test "$BITS_CHECK_64" = "yes"; then
+            AC_MSG_CHECKING([how to build 64-bit executables])
+            CAN_BUILD_64=no
+            ####
+            # Find out if we think we can *build* for 64 bit. Doesn't check whether we can run it.
+            #  Note, we don't have to actually check if the options work- we'll try them before using them.
+            #  So, only try actually testing the options, if you are trying to decide between multiple options.
+            # On exit from the following clauses:
+            # if CAN_BUILD_64=yes:
+            #    *FLAGS are assumed to contain the right settings for 64bit
+            # else if CAN_BUILD_64=no: (default)
+            #    *FLAGS are assumed to be trashed, and will be reset from *FLAGS_OLD
+            
+            if test "$GCC" = yes; then
+                CFLAGS="${CFLAGS} -m64"
+                CXXFLAGS="${CXXFLAGS} -m64"
+                AC_COMPILE_IFELSE(int main(void) {return (sizeof(void*)*8==64)?0:1;},
+                   CAN_BUILD_64=yes, CAN_BUILD_64=no)
+            else
+                case "${host}" in
+                sparc*-*-solaris*)
+                    # 1. try -m64
+                    CFLAGS="${CFLAGS} -m64"
+                    CXXFLAGS="${CXXFLAGS} -m64"
+                    AC_COMPILE_IFELSE(int main(void) {return (sizeof(void*)*8==64)?0:1;},
+                       CAN_BUILD_64=yes, CAN_BUILD_64=no)
+                    if test "$CAN_BUILD_64" != yes; then
+                        # Nope. back out changes.
+                        CFLAGS="${CFLAGS_OLD}"
+                        CXXFLAGS="${CFLAGS_OLD}"
+                        # 2. try xarch=v9 [deprecated]
+                        ## TODO: cross compile: the following won't work.
+                        SPARCV9=`isainfo -n 2>&1 | grep sparcv9`
+                        SOL64=`$CXX -xarch=v9 2>&1 && $CC -xarch=v9 2>&1 | grep -v usage:`
+                        # "Warning: -xarch=v9 is deprecated, use -m64 to create 64-bit programs"
+                        if test -z "$SOL64" && test -n "$SPARCV9"; then
+                            CFLAGS="${CFLAGS} -xtarget=ultra -xarch=v9"
+                            CXXFLAGS="${CXXFLAGS} -xtarget=ultra -xarch=v9"
+                            LDFLAGS="${LDFLAGS} -xtarget=ultra -xarch=v9"
+                            CAN_BUILD_64=yes
+                        fi
+                    fi
+                    ;;
+                i386-*-solaris*)
+                    # 1. try -m64
+                    CFLAGS="${CFLAGS} -m64"
+                    CXXFLAGS="${CXXFLAGS} -m64"
+                    AC_COMPILE_IFELSE(int main(void) {return (sizeof(void*)*8==64)?0:1;},
+                       CAN_BUILD_64=yes, CAN_BUILD_64=no)
+                    if test "$CAN_BUILD_64" != yes; then
+                        # Nope. back out changes.
+                        CFLAGS="${CFLAGS_OLD}"
+                        CXXFLAGS="${CXXFLAGS_OLD}"
+                        # 2. try the older compiler option
+                        ## TODO: cross compile problem
+                        SOL64=`$CXX -xtarget=generic64 2>&1 && $CC -xtarget=generic64 2>&1 | grep -v usage:`
+                        if test -z "$SOL64" && test -n "$AMD64"; then
+                            CFLAGS="${CFLAGS} -xtarget=generic64"
+                            CXXFLAGS="${CXXFLAGS} -xtarget=generic64"
+                            CAN_BUILD_64=yes
+                        fi
+                    fi
+                    ;;
+                ia64-*-linux*)
+                    # check for ecc/ecpc compiler support
+                    ## TODO: cross compiler problem
+                    if test -n "`$CXX --help 2>&1 && $CC --help 2>&1 | grep -v Intel`"; then
+                        if test -n "`$CXX --help 2>&1 && $CC --help 2>&1 | grep -v Itanium`"; then
+                            CAN_BUILD_64=yes
+                        fi
+                    fi
+                    ;;
+                *-*-cygwin)
+                    # vcvarsamd64.bat should have been used to enable 64-bit builds.
+                    # We only do this check to display the correct answer.
+                    ## TODO: cross compiler problem
+                    if test -n "`$CXX -help 2>&1 | grep 'for x64'`"; then
+                        CAN_BUILD_64=yes
+                    fi
+                    ;;
+                *-*-aix*|powerpc64-*-linux*)
+                    CFLAGS="${CFLAGS} -q64"
+                    CXXFLAGS="${CXXFLAGS} -q64"
+                    LDFLAGS="${LDFLAGS} -q64"
+                    AC_COMPILE_IFELSE(int main(void) {return (sizeof(void*)*8==64)?0:1;},
+                       CAN_BUILD_64=yes, CAN_BUILD_64=no)
+                    if test "$CAN_BUILD_64" = yes; then
+                        # worked- set other options.
+                        case "${host}" in
+                        *-*-aix*)
+                            # tell AIX what executable mode to use.
+                            ARFLAGS="${ARFLAGS} -X64"
+                        esac
+                    fi
+                    ;;
+                *-*-hpux*)
+                    # First we try the newer +DD64, if that doesn't work,
+                    # try other options.
+
+                    CFLAGS="${CFLAGS} +DD64"
+                    CXXFLAGS="${CXXFLAGS} +DD64"
+                    AC_COMPILE_IFELSE(int main(void) {return (sizeof(void*)*8==64)?0:1;},
+                        CAN_BUILD_64=yes, CAN_BUILD_64=no)
+                    if test "$CAN_BUILD_64" != yes; then
+                        # reset
+                        CFLAGS="${CFLAGS_OLD}"
+                        CXXFLAGS="${CXXFLAGS_OLD}"
+                        # append
+                        CFLAGS="${CFLAGS} +DA2.0W"
+                        CXXFLAGS="${CXXFLAGS} +DA2.0W"
+                        AC_COMPILE_IFELSE(int main(void) {return (sizeof(void*)*8==64)?0:1;},
+                            CAN_BUILD_64=yes, CAN_BUILD_64=no)
+                    fi
+                    ;;
+                *-*ibm-openedition*|*-*-os390*)
+                    CFLAGS="${CFLAGS} -Wc,lp64"
+                    CXXFLAGS="${CXXFLAGS} -Wc,lp64"
+                    LDFLAGS="${LDFLAGS} -Wl,lp64"
+                    AC_COMPILE_IFELSE(int main(void) {return (sizeof(void*)*8==64)?0:1;},
+                       CAN_BUILD_64=yes, CAN_BUILD_64=no)
+                    ;;
+                *)
+                    # unknown platform.
+                    ;;
+                esac
+            fi
+            AC_MSG_RESULT($CAN_BUILD_64)
+            if test "$CAN_BUILD_64" = yes; then
+                AC_MSG_CHECKING([whether runnable 64-bit binaries are being built ])
+                AC_TRY_RUN(int main(void) {return (sizeof(void*)*8==64)?0:1;},
+                   BITS_RUN_64=yes, BITS_RUN_64=no, BITS_RUN_64=unknown)
+                AC_MSG_RESULT($BITS_RUN_64);
+
+                CFLAGS_64="${CFLAGS}"
+                CXXFLAGS_64="${CXXFLAGS}"
+                LDFLAGS_64="${LDFLAGS}"
+                ARFLAGS_64="${ARFLAGS}"        
+            fi
+            # put it back.
+            CFLAGS="${CFLAGS_OLD}"
+            CXXFLAGS="${CXXFLAGS_OLD}"
+            LDFLAGS="${LDFLAGS_OLD}"
+            ARFLAGS="${ARFLAGS_OLD}"     
+        fi
+        if test "$BITS_CHECK_32" = "yes"; then
+            # see comment under 'if BITS_CHECK_64', above.
+            AC_MSG_CHECKING([how to build 32-bit executables])
+            if test "$GCC" = yes; then
+                CFLAGS="${CFLAGS} -m32"
+                CXXFLAGS="${CXXFLAGS} -m32"
+                AC_COMPILE_IFELSE(int main(void) {return (sizeof(void*)*8==32)?0:1;},
+                   CAN_BUILD_32=yes, CAN_BUILD_32=no)
+            fi
+            AC_MSG_RESULT($CAN_BUILD_32)
+            if test "$CAN_BUILD_32" = yes; then
+                AC_MSG_CHECKING([whether runnable 32-bit binaries are being built ])
+                AC_TRY_RUN(int main(void) {return (sizeof(void*)*8==32)?0:1;},
+                   BITS_RUN_32=yes, BITS_RUN_32=no, BITS_RUN_32=unknown)
+                AC_MSG_RESULT($BITS_RUN_32);
+                CFLAGS_32="${CFLAGS}"
+                CXXFLAGS_32="${CXXFLAGS}"
+                LDFLAGS_32="${LDFLAGS}"
+                ARFLAGS_32="${ARFLAGS}"        
+            fi
+            # put it back.
+            CFLAGS="${CFLAGS_OLD}"
+            CXXFLAGS="${CXXFLAGS_OLD}"
+            LDFLAGS="${LDFLAGS_OLD}"
+            ARFLAGS="${ARFLAGS_OLD}"     
+        fi
+        
+        ##
+        # OK. Now, we've tested for 32 and 64 bitness. Let's see what we'll do.
+        #
+        
+        # First, implement 64else32
+        if test "$BITS_REQ" = "64else32"; then
+            if test "$BITS_RUN_64" = "yes"; then
+                BITS_REQ=64
+            else
+                # no changes.
+                BITS_OK=yes 
+            fi
+        fi
+        
+        # implement.
+        if test "$BITS_REQ" = "32" -a "$BITS_RUN_32" = "yes"; then
+            CFLAGS="${CFLAGS_32}"
+            CXXFLAGS="${CXXFLAGS_32}"
+            LDFLAGS="${LDFLAGS_32}"
+            ARFLAGS="${ARFLAGS_32}"     
+            BITS_OK=yes
+        elif test "$BITS_REQ" = "64" -a "$BITS_RUN_64" = "yes"; then
+            CFLAGS="${CFLAGS_64}"
+            CXXFLAGS="${CXXFLAGS_64}"
+            LDFLAGS="${LDFLAGS_64}"
+            ARFLAGS="${ARFLAGS_64}"     
+            BITS_OK=yes
+        elif test "$BITS_OK" != "yes"; then
+            AC_MSG_ERROR([Requested $BITS_REQ bit binaries but could not compile and execute them. See readme.html for help with cross compilation., and set compiler options manually.])
+        fi
+     fi
+])
+
+# Strict compilation options.
+AC_DEFUN(AC_CHECK_STRICT_COMPILE,
+[
+    AC_MSG_CHECKING([whether strict compiling is on])
+    AC_ARG_ENABLE(strict,[  --enable-strict         compile with strict compiler options [default=yes]], [
+        if test "$enableval" = no
+        then
+            ac_use_strict_options=no
+        else
+            ac_use_strict_options=yes
+        fi
+      ], [ac_use_strict_options=yes])
+    AC_MSG_RESULT($ac_use_strict_options)
+
+    if test "$ac_use_strict_options" = yes
+    then
+        if test "$GCC" = yes
+        then
+            CFLAGS="$CFLAGS -Wall -ansi -pedantic -Wshadow -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -Wno-long-long"
+            case "${host}" in
+            *-*-solaris*)
+                CFLAGS="$CFLAGS -D__STDC__=0";;
+            esac
+        else
+            case "${host}" in
+            *-*-cygwin)
+                if test "`$CC /help 2>&1 | head -c9`" = "Microsoft"
+                then
+                    CFLAGS="$CFLAGS /W4"
+                fi
+            esac
+        fi
+        if test "$GXX" = yes
+        then
+            CXXFLAGS="$CXXFLAGS -W -Wall -ansi -pedantic -Wpointer-arith -Wwrite-strings -Wno-long-long"
+            case "${host}" in
+            *-*-solaris*)
+                CXXFLAGS="$CXXFLAGS -D__STDC__=0";;
+            esac
+        else
+            case "${host}" in
+            *-*-cygwin)
+                if test "`$CXX /help 2>&1 | head -c9`" = "Microsoft"
+                then
+                    CXXFLAGS="$CXXFLAGS /W4"
+                fi
+            esac
+        fi
+    fi
+])
+
+
diff --git a/icu/source/allinone/allinone.sln b/icu/source/allinone/allinone.sln
new file mode 100644
index 0000000..a9c5693
--- /dev/null
+++ b/icu/source/allinone/allinone.sln
@@ -0,0 +1,596 @@
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cal", "..\samples\cal\cal.vcproj", "{F7659D77-09CF-4FE9-ACEE-927287AA9509}"
+	ProjectSection(ProjectDependencies) = postProject
+		{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cintltst", "..\test\cintltst\cintltst.vcproj", "{3D1246AE-1B32-479B-BECA-AEFA97BE2321}"
+	ProjectSection(ProjectDependencies) = postProject
+		{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47} = {ECA6B435-B4FA-4F9F-BF95-F451D078FC47}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "..\common\common.vcproj", "{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}"
+	ProjectSection(ProjectDependencies) = postProject
+		{203EC78A-0531-43F0-A636-285439BDE025} = {203EC78A-0531-43F0-A636-285439BDE025}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ctestfw", "..\tools\ctestfw\ctestfw.vcproj", "{ECA6B435-B4FA-4F9F-BF95-F451D078FC47}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "date", "..\samples\date\date.vcproj", "{38B5751A-C6F9-4409-950C-F4F9DA17275F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "derb", "..\tools\genrb\derb.vcproj", "{D3065ADB-8820-4CC7-9B6C-9510833961A3}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genbrk", "..\tools\genbrk\genbrk.vcproj", "{C2BE5000-7501-4E87-9724-B8D82494FAE6}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genccode", "..\tools\genccode\genccode.vcproj", "{FDD3C4F2-9805-44EB-9A77-BC1C1C95B547}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gencmn", "..\tools\gencmn\gencmn.vcproj", "{A8D36F8D-09E6-4174-91C3-7BEAA9C3F04F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gencnval", "..\tools\gencnval\gencnval.vcproj", "{8B41752B-5A52-41E4-B7E0-07921C0CC6BF}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gennames", "..\tools\gennames\gennames.vcproj", "{F5281B04-A9E0-4680-BBA8-1D7F7D115458}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genpname", "..\tools\genpname\genpname.vcproj", "{DBC0AF0B-B9FF-4B23-905B-4D4CDC2A91CB}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genprops", "..\tools\genprops\genprops.vcproj", "{6F744648-D15F-478A-90C6-58E353B5DDB3}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genrb", "..\tools\genrb\genrb.vcproj", "{97521D06-EC47-45D4-8BD0-9E16B3F93B2A}"
+	ProjectSection(ProjectDependencies) = postProject
+		{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gentest", "..\tools\gentest\gentest.vcproj", "{77C78066-746F-4EA6-B3FE-B8C8A4A97891}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47} = {ECA6B435-B4FA-4F9F-BF95-F451D078FC47}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genuca", "..\tools\genuca\genuca.vcproj", "{86829694-A375-4C58-B4EA-96EF514E3225}"
+	ProjectSection(ProjectDependencies) = postProject
+		{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "i18n", "..\i18n\i18n.vcproj", "{0178B127-6269-407D-B112-93877BB62776}"
+	ProjectSection(ProjectDependencies) = postProject
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "intltest", "..\test\intltest\intltest.vcproj", "{73632960-B3A6-464D-83A3-4B43365F19B8}"
+	ProjectSection(ProjectDependencies) = postProject
+		{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47} = {ECA6B435-B4FA-4F9F-BF95-F451D078FC47}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "layout", "..\layout\layout.vcproj", "{C920062A-0647-4553-A3B2-37C58065664B}"
+	ProjectSection(ProjectDependencies) = postProject
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "layoutex", "..\layoutex\layoutex.vcproj", "{37FC2C7F-1904-4811-8955-2F478830EAD1}"
+	ProjectSection(ProjectDependencies) = postProject
+		{C920062A-0647-4553-A3B2-37C58065664B} = {C920062A-0647-4553-A3B2-37C58065664B}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "makeconv", "..\tools\makeconv\makeconv.vcproj", "{F5AD9738-1A3D-4906-B9C4-A7D9CE33DC2C}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "makedata", "..\data\makedata.vcproj", "{D9DF7F2F-93B7-4810-B5CD-96F4F33C079B}"
+	ProjectSection(ProjectDependencies) = postProject
+		{C2BE5000-7501-4E87-9724-B8D82494FAE6} = {C2BE5000-7501-4E87-9724-B8D82494FAE6}
+		{F5281B04-A9E0-4680-BBA8-1D7F7D115458} = {F5281B04-A9E0-4680-BBA8-1D7F7D115458}
+		{97521D06-EC47-45D4-8BD0-9E16B3F93B2A} = {97521D06-EC47-45D4-8BD0-9E16B3F93B2A}
+		{C2B04507-2521-4801-BF0D-5FD79D6D518C} = {C2B04507-2521-4801-BF0D-5FD79D6D518C}
+		{DBC0AF0B-B9FF-4B23-905B-4D4CDC2A91CB} = {DBC0AF0B-B9FF-4B23-905B-4D4CDC2A91CB}
+		{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
+		{C920062A-0647-4553-A3B2-37C58065664B} = {C920062A-0647-4553-A3B2-37C58065664B}
+		{8B41752B-5A52-41E4-B7E0-07921C0CC6BF} = {8B41752B-5A52-41E4-B7E0-07921C0CC6BF}
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47} = {ECA6B435-B4FA-4F9F-BF95-F451D078FC47}
+		{F5AD9738-1A3D-4906-B9C4-A7D9CE33DC2C} = {F5AD9738-1A3D-4906-B9C4-A7D9CE33DC2C}
+		{6F744648-D15F-478A-90C6-58E353B5DDB3} = {6F744648-D15F-478A-90C6-58E353B5DDB3}
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF61} = {DB312A49-12A9-4E07-9E96-451DC2D8FF61}
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF62} = {DB312A49-12A9-4E07-9E96-451DC2D8FF62}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+		{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC} = {62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}
+		{73632960-B3A6-464D-83A3-4B43365F19B8} = {73632960-B3A6-464D-83A3-4B43365F19B8}
+		{C7891A65-80AB-4245-912E-5F1E17B0E6C4} = {C7891A65-80AB-4245-912E-5F1E17B0E6C4}
+		{77C78066-746F-4EA6-B3FE-B8C8A4A97891} = {77C78066-746F-4EA6-B3FE-B8C8A4A97891}
+		{37FC2C7F-1904-4811-8955-2F478830EAD1} = {37FC2C7F-1904-4811-8955-2F478830EAD1}
+		{E4993E82-D68A-46CA-BAE0-9D35E172E46F} = {E4993E82-D68A-46CA-BAE0-9D35E172E46F}
+		{67351485-4D18-4245-BE39-A7EF0675ACD2} = {67351485-4D18-4245-BE39-A7EF0675ACD2}
+		{203EC78A-0531-43F0-A636-285439BDE025} = {203EC78A-0531-43F0-A636-285439BDE025}
+		{DBA4088D-F6F9-4F8F-8820-082A4765C16C} = {DBA4088D-F6F9-4F8F-8820-082A4765C16C}
+		{A8D36F8D-09E6-4174-91C3-7BEAA9C3F04F} = {A8D36F8D-09E6-4174-91C3-7BEAA9C3F04F}
+		{86829694-A375-4C58-B4EA-96EF514E3225} = {86829694-A375-4C58-B4EA-96EF514E3225}
+		{3D1246AE-1B32-479B-BECA-AEFA97BE2321} = {3D1246AE-1B32-479B-BECA-AEFA97BE2321}
+		{691EE0C0-DC57-4A48-8AEE-8ED75EB3A057} = {691EE0C0-DC57-4A48-8AEE-8ED75EB3A057}
+		{631C23CE-6C1D-4875-88F0-85E0A42B36EA} = {631C23CE-6C1D-4875-88F0-85E0A42B36EA}
+		{D3065ADB-8820-4CC7-9B6C-9510833961A3} = {D3065ADB-8820-4CC7-9B6C-9510833961A3}
+		{FDD3C4F2-9805-44EB-9A77-BC1C1C95B547} = {FDD3C4F2-9805-44EB-9A77-BC1C1C95B547}
+		{9D4211F7-2C77-439C-82F0-30A4E43BA569} = {9D4211F7-2C77-439C-82F0-30A4E43BA569}
+		{4C8454FE-81D3-4CA3-9927-29BA96F03DAC} = {4C8454FE-81D3-4CA3-9927-29BA96F03DAC}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pkgdata", "..\tools\pkgdata\pkgdata.vcproj", "{4C8454FE-81D3-4CA3-9927-29BA96F03DAC}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+		{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC} = {62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}
+		{A8D36F8D-09E6-4174-91C3-7BEAA9C3F04F} = {A8D36F8D-09E6-4174-91C3-7BEAA9C3F04F}
+		{FDD3C4F2-9805-44EB-9A77-BC1C1C95B547} = {FDD3C4F2-9805-44EB-9A77-BC1C1C95B547}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stubdata", "..\stubdata\stubdata.vcproj", "{203EC78A-0531-43F0-A636-285439BDE025}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "toolutil", "..\tools\toolutil\toolutil.vcproj", "{6B231032-3CB5-4EED-9210-810D666A23A0}"
+	ProjectSection(ProjectDependencies) = postProject
+		{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uconv", "..\extra\uconv\uconv.vcproj", "{DBA4088D-F6F9-4F8F-8820-082A4765C16C}"
+	ProjectSection(ProjectDependencies) = postProject
+		{97521D06-EC47-45D4-8BD0-9E16B3F93B2A} = {97521D06-EC47-45D4-8BD0-9E16B3F93B2A}
+		{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+		{4C8454FE-81D3-4CA3-9927-29BA96F03DAC} = {4C8454FE-81D3-4CA3-9927-29BA96F03DAC}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "io", "..\io\io.vcproj", "{C2B04507-2521-4801-BF0D-5FD79D6D518C}"
+	ProjectSection(ProjectDependencies) = postProject
+		{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gensprep", "..\tools\gensprep\gensprep.vcproj", "{631C23CE-6C1D-4875-88F0-85E0A42B36EA}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iotest", "..\test\iotest\iotest.vcproj", "{E4993E82-D68A-46CA-BAE0-9D35E172E46F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{C2B04507-2521-4801-BF0D-5FD79D6D518C} = {C2B04507-2521-4801-BF0D-5FD79D6D518C}
+		{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47} = {ECA6B435-B4FA-4F9F-BF95-F451D078FC47}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genbidi", "..\tools\genbidi\genbidi.vcproj", "{DB312A49-12A9-4E07-9E96-451DC2D8FF62}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gencase", "..\tools\gencase\gencase.vcproj", "{DB312A49-12A9-4E07-9E96-451DC2D8FF61}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icupkg", "..\tools\icupkg\icupkg.vcproj", "{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genctd", "..\tools\genctd\genctd.vcproj", "{9D4211F7-2C77-439C-82F0-30A4E43BA569}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "letest", "..\test\letest\letest.vcproj", "{67351485-4D18-4245-BE39-A7EF0675ACD2}"
+	ProjectSection(ProjectDependencies) = postProject
+		{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
+		{C920062A-0647-4553-A3B2-37C58065664B} = {C920062A-0647-4553-A3B2-37C58065664B}
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47} = {ECA6B435-B4FA-4F9F-BF95-F451D078FC47}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+		{37FC2C7F-1904-4811-8955-2F478830EAD1} = {37FC2C7F-1904-4811-8955-2F478830EAD1}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gencfu", "..\tools\gencfu\gencfu.vcproj", "{691EE0C0-DC57-4A48-8AEE-8ED75EB3A057}"
+	ProjectSection(ProjectDependencies) = postProject
+		{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gennorm2", "..\tools\gennorm2\gennorm2.vcproj", "{C7891A65-80AB-4245-912E-5F1E17B0E6C4}"
+	ProjectSection(ProjectDependencies) = postProject
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icuinfo", "..\tools\icuinfo\icuinfo.vcproj", "{E7611F49-F088-4175-9446-6111444E72C8}"
+	ProjectSection(ProjectDependencies) = postProject
+		{0178B127-6269-407D-B112-93877BB62776} = {0178B127-6269-407D-B112-93877BB62776}
+		{6B231032-3CB5-4EED-9210-810D666A23A0} = {6B231032-3CB5-4EED-9210-810D666A23A0}
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47} = {ECA6B435-B4FA-4F9F-BF95-F451D078FC47}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testplug", "..\tools\icuinfo\testplug.vcproj", "{659D0C08-D4ED-4BF3-B02B-2D8D4B5A7A7A}"
+	ProjectSection(ProjectDependencies) = postProject
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47} = {ECA6B435-B4FA-4F9F-BF95-F451D078FC47}
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D} = {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{F7659D77-09CF-4FE9-ACEE-927287AA9509}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F7659D77-09CF-4FE9-ACEE-927287AA9509}.Debug|Win32.Build.0 = Debug|Win32
+		{F7659D77-09CF-4FE9-ACEE-927287AA9509}.Debug|x64.ActiveCfg = Debug|x64
+		{F7659D77-09CF-4FE9-ACEE-927287AA9509}.Debug|x64.Build.0 = Debug|x64
+		{F7659D77-09CF-4FE9-ACEE-927287AA9509}.Release|Win32.ActiveCfg = Release|Win32
+		{F7659D77-09CF-4FE9-ACEE-927287AA9509}.Release|Win32.Build.0 = Release|Win32
+		{F7659D77-09CF-4FE9-ACEE-927287AA9509}.Release|x64.ActiveCfg = Release|x64
+		{F7659D77-09CF-4FE9-ACEE-927287AA9509}.Release|x64.Build.0 = Release|x64
+		{3D1246AE-1B32-479B-BECA-AEFA97BE2321}.Debug|Win32.ActiveCfg = Debug|Win32
+		{3D1246AE-1B32-479B-BECA-AEFA97BE2321}.Debug|Win32.Build.0 = Debug|Win32
+		{3D1246AE-1B32-479B-BECA-AEFA97BE2321}.Debug|x64.ActiveCfg = Debug|x64
+		{3D1246AE-1B32-479B-BECA-AEFA97BE2321}.Debug|x64.Build.0 = Debug|x64
+		{3D1246AE-1B32-479B-BECA-AEFA97BE2321}.Release|Win32.ActiveCfg = Release|Win32
+		{3D1246AE-1B32-479B-BECA-AEFA97BE2321}.Release|Win32.Build.0 = Release|Win32
+		{3D1246AE-1B32-479B-BECA-AEFA97BE2321}.Release|x64.ActiveCfg = Release|x64
+		{3D1246AE-1B32-479B-BECA-AEFA97BE2321}.Release|x64.Build.0 = Release|x64
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Debug|Win32.Build.0 = Debug|Win32
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Debug|x64.ActiveCfg = Debug|x64
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Debug|x64.Build.0 = Debug|x64
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Release|Win32.ActiveCfg = Release|Win32
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Release|Win32.Build.0 = Release|Win32
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Release|x64.ActiveCfg = Release|x64
+		{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Release|x64.Build.0 = Release|x64
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47}.Debug|Win32.ActiveCfg = Debug|Win32
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47}.Debug|Win32.Build.0 = Debug|Win32
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47}.Debug|x64.ActiveCfg = Debug|x64
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47}.Debug|x64.Build.0 = Debug|x64
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47}.Release|Win32.ActiveCfg = Release|Win32
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47}.Release|Win32.Build.0 = Release|Win32
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47}.Release|x64.ActiveCfg = Release|x64
+		{ECA6B435-B4FA-4F9F-BF95-F451D078FC47}.Release|x64.Build.0 = Release|x64
+		{38B5751A-C6F9-4409-950C-F4F9DA17275F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{38B5751A-C6F9-4409-950C-F4F9DA17275F}.Debug|Win32.Build.0 = Debug|Win32
+		{38B5751A-C6F9-4409-950C-F4F9DA17275F}.Debug|x64.ActiveCfg = Debug|x64
+		{38B5751A-C6F9-4409-950C-F4F9DA17275F}.Debug|x64.Build.0 = Debug|x64
+		{38B5751A-C6F9-4409-950C-F4F9DA17275F}.Release|Win32.ActiveCfg = Release|Win32
+		{38B5751A-C6F9-4409-950C-F4F9DA17275F}.Release|Win32.Build.0 = Release|Win32
+		{38B5751A-C6F9-4409-950C-F4F9DA17275F}.Release|x64.ActiveCfg = Release|x64
+		{38B5751A-C6F9-4409-950C-F4F9DA17275F}.Release|x64.Build.0 = Release|x64
+		{D3065ADB-8820-4CC7-9B6C-9510833961A3}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D3065ADB-8820-4CC7-9B6C-9510833961A3}.Debug|Win32.Build.0 = Debug|Win32
+		{D3065ADB-8820-4CC7-9B6C-9510833961A3}.Debug|x64.ActiveCfg = Debug|x64
+		{D3065ADB-8820-4CC7-9B6C-9510833961A3}.Debug|x64.Build.0 = Debug|x64
+		{D3065ADB-8820-4CC7-9B6C-9510833961A3}.Release|Win32.ActiveCfg = Release|Win32
+		{D3065ADB-8820-4CC7-9B6C-9510833961A3}.Release|Win32.Build.0 = Release|Win32
+		{D3065ADB-8820-4CC7-9B6C-9510833961A3}.Release|x64.ActiveCfg = Release|x64
+		{D3065ADB-8820-4CC7-9B6C-9510833961A3}.Release|x64.Build.0 = Release|x64
+		{C2BE5000-7501-4E87-9724-B8D82494FAE6}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C2BE5000-7501-4E87-9724-B8D82494FAE6}.Debug|Win32.Build.0 = Debug|Win32
+		{C2BE5000-7501-4E87-9724-B8D82494FAE6}.Debug|x64.ActiveCfg = Debug|x64
+		{C2BE5000-7501-4E87-9724-B8D82494FAE6}.Debug|x64.Build.0 = Debug|x64
+		{C2BE5000-7501-4E87-9724-B8D82494FAE6}.Release|Win32.ActiveCfg = Release|Win32
+		{C2BE5000-7501-4E87-9724-B8D82494FAE6}.Release|Win32.Build.0 = Release|Win32
+		{C2BE5000-7501-4E87-9724-B8D82494FAE6}.Release|x64.ActiveCfg = Release|x64
+		{C2BE5000-7501-4E87-9724-B8D82494FAE6}.Release|x64.Build.0 = Release|x64
+		{FDD3C4F2-9805-44EB-9A77-BC1C1C95B547}.Debug|Win32.ActiveCfg = Debug|Win32
+		{FDD3C4F2-9805-44EB-9A77-BC1C1C95B547}.Debug|Win32.Build.0 = Debug|Win32
+		{FDD3C4F2-9805-44EB-9A77-BC1C1C95B547}.Debug|x64.ActiveCfg = Debug|x64
+		{FDD3C4F2-9805-44EB-9A77-BC1C1C95B547}.Debug|x64.Build.0 = Debug|x64
+		{FDD3C4F2-9805-44EB-9A77-BC1C1C95B547}.Release|Win32.ActiveCfg = Release|Win32
+		{FDD3C4F2-9805-44EB-9A77-BC1C1C95B547}.Release|Win32.Build.0 = Release|Win32
+		{FDD3C4F2-9805-44EB-9A77-BC1C1C95B547}.Release|x64.ActiveCfg = Release|x64
+		{FDD3C4F2-9805-44EB-9A77-BC1C1C95B547}.Release|x64.Build.0 = Release|x64
+		{A8D36F8D-09E6-4174-91C3-7BEAA9C3F04F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{A8D36F8D-09E6-4174-91C3-7BEAA9C3F04F}.Debug|Win32.Build.0 = Debug|Win32
+		{A8D36F8D-09E6-4174-91C3-7BEAA9C3F04F}.Debug|x64.ActiveCfg = Debug|x64
+		{A8D36F8D-09E6-4174-91C3-7BEAA9C3F04F}.Debug|x64.Build.0 = Debug|x64
+		{A8D36F8D-09E6-4174-91C3-7BEAA9C3F04F}.Release|Win32.ActiveCfg = Release|Win32
+		{A8D36F8D-09E6-4174-91C3-7BEAA9C3F04F}.Release|Win32.Build.0 = Release|Win32
+		{A8D36F8D-09E6-4174-91C3-7BEAA9C3F04F}.Release|x64.ActiveCfg = Release|x64
+		{A8D36F8D-09E6-4174-91C3-7BEAA9C3F04F}.Release|x64.Build.0 = Release|x64
+		{8B41752B-5A52-41E4-B7E0-07921C0CC6BF}.Debug|Win32.ActiveCfg = Debug|Win32
+		{8B41752B-5A52-41E4-B7E0-07921C0CC6BF}.Debug|Win32.Build.0 = Debug|Win32
+		{8B41752B-5A52-41E4-B7E0-07921C0CC6BF}.Debug|x64.ActiveCfg = Debug|x64
+		{8B41752B-5A52-41E4-B7E0-07921C0CC6BF}.Debug|x64.Build.0 = Debug|x64
+		{8B41752B-5A52-41E4-B7E0-07921C0CC6BF}.Release|Win32.ActiveCfg = Release|Win32
+		{8B41752B-5A52-41E4-B7E0-07921C0CC6BF}.Release|Win32.Build.0 = Release|Win32
+		{8B41752B-5A52-41E4-B7E0-07921C0CC6BF}.Release|x64.ActiveCfg = Release|x64
+		{8B41752B-5A52-41E4-B7E0-07921C0CC6BF}.Release|x64.Build.0 = Release|x64
+		{F5281B04-A9E0-4680-BBA8-1D7F7D115458}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F5281B04-A9E0-4680-BBA8-1D7F7D115458}.Debug|Win32.Build.0 = Debug|Win32
+		{F5281B04-A9E0-4680-BBA8-1D7F7D115458}.Debug|x64.ActiveCfg = Debug|x64
+		{F5281B04-A9E0-4680-BBA8-1D7F7D115458}.Debug|x64.Build.0 = Debug|x64
+		{F5281B04-A9E0-4680-BBA8-1D7F7D115458}.Release|Win32.ActiveCfg = Release|Win32
+		{F5281B04-A9E0-4680-BBA8-1D7F7D115458}.Release|Win32.Build.0 = Release|Win32
+		{F5281B04-A9E0-4680-BBA8-1D7F7D115458}.Release|x64.ActiveCfg = Release|x64
+		{F5281B04-A9E0-4680-BBA8-1D7F7D115458}.Release|x64.Build.0 = Release|x64
+		{DBC0AF0B-B9FF-4B23-905B-4D4CDC2A91CB}.Debug|Win32.ActiveCfg = Debug|Win32
+		{DBC0AF0B-B9FF-4B23-905B-4D4CDC2A91CB}.Debug|Win32.Build.0 = Debug|Win32
+		{DBC0AF0B-B9FF-4B23-905B-4D4CDC2A91CB}.Debug|x64.ActiveCfg = Debug|x64
+		{DBC0AF0B-B9FF-4B23-905B-4D4CDC2A91CB}.Debug|x64.Build.0 = Debug|x64
+		{DBC0AF0B-B9FF-4B23-905B-4D4CDC2A91CB}.Release|Win32.ActiveCfg = Release|Win32
+		{DBC0AF0B-B9FF-4B23-905B-4D4CDC2A91CB}.Release|Win32.Build.0 = Release|Win32
+		{DBC0AF0B-B9FF-4B23-905B-4D4CDC2A91CB}.Release|x64.ActiveCfg = Release|x64
+		{DBC0AF0B-B9FF-4B23-905B-4D4CDC2A91CB}.Release|x64.Build.0 = Release|x64
+		{6F744648-D15F-478A-90C6-58E353B5DDB3}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6F744648-D15F-478A-90C6-58E353B5DDB3}.Debug|Win32.Build.0 = Debug|Win32
+		{6F744648-D15F-478A-90C6-58E353B5DDB3}.Debug|x64.ActiveCfg = Debug|x64
+		{6F744648-D15F-478A-90C6-58E353B5DDB3}.Debug|x64.Build.0 = Debug|x64
+		{6F744648-D15F-478A-90C6-58E353B5DDB3}.Release|Win32.ActiveCfg = Release|Win32
+		{6F744648-D15F-478A-90C6-58E353B5DDB3}.Release|Win32.Build.0 = Release|Win32
+		{6F744648-D15F-478A-90C6-58E353B5DDB3}.Release|x64.ActiveCfg = Release|x64
+		{6F744648-D15F-478A-90C6-58E353B5DDB3}.Release|x64.Build.0 = Release|x64
+		{97521D06-EC47-45D4-8BD0-9E16B3F93B2A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{97521D06-EC47-45D4-8BD0-9E16B3F93B2A}.Debug|Win32.Build.0 = Debug|Win32
+		{97521D06-EC47-45D4-8BD0-9E16B3F93B2A}.Debug|x64.ActiveCfg = Debug|x64
+		{97521D06-EC47-45D4-8BD0-9E16B3F93B2A}.Debug|x64.Build.0 = Debug|x64
+		{97521D06-EC47-45D4-8BD0-9E16B3F93B2A}.Release|Win32.ActiveCfg = Release|Win32
+		{97521D06-EC47-45D4-8BD0-9E16B3F93B2A}.Release|Win32.Build.0 = Release|Win32
+		{97521D06-EC47-45D4-8BD0-9E16B3F93B2A}.Release|x64.ActiveCfg = Release|x64
+		{97521D06-EC47-45D4-8BD0-9E16B3F93B2A}.Release|x64.Build.0 = Release|x64
+		{77C78066-746F-4EA6-B3FE-B8C8A4A97891}.Debug|Win32.ActiveCfg = Debug|Win32
+		{77C78066-746F-4EA6-B3FE-B8C8A4A97891}.Debug|Win32.Build.0 = Debug|Win32
+		{77C78066-746F-4EA6-B3FE-B8C8A4A97891}.Debug|x64.ActiveCfg = Debug|x64
+		{77C78066-746F-4EA6-B3FE-B8C8A4A97891}.Debug|x64.Build.0 = Debug|x64
+		{77C78066-746F-4EA6-B3FE-B8C8A4A97891}.Release|Win32.ActiveCfg = Release|Win32
+		{77C78066-746F-4EA6-B3FE-B8C8A4A97891}.Release|Win32.Build.0 = Release|Win32
+		{77C78066-746F-4EA6-B3FE-B8C8A4A97891}.Release|x64.ActiveCfg = Release|x64
+		{77C78066-746F-4EA6-B3FE-B8C8A4A97891}.Release|x64.Build.0 = Release|x64
+		{86829694-A375-4C58-B4EA-96EF514E3225}.Debug|Win32.ActiveCfg = Debug|Win32
+		{86829694-A375-4C58-B4EA-96EF514E3225}.Debug|Win32.Build.0 = Debug|Win32
+		{86829694-A375-4C58-B4EA-96EF514E3225}.Debug|x64.ActiveCfg = Debug|x64
+		{86829694-A375-4C58-B4EA-96EF514E3225}.Debug|x64.Build.0 = Debug|x64
+		{86829694-A375-4C58-B4EA-96EF514E3225}.Release|Win32.ActiveCfg = Release|Win32
+		{86829694-A375-4C58-B4EA-96EF514E3225}.Release|Win32.Build.0 = Release|Win32
+		{86829694-A375-4C58-B4EA-96EF514E3225}.Release|x64.ActiveCfg = Release|x64
+		{86829694-A375-4C58-B4EA-96EF514E3225}.Release|x64.Build.0 = Release|x64
+		{0178B127-6269-407D-B112-93877BB62776}.Debug|Win32.ActiveCfg = Debug|Win32
+		{0178B127-6269-407D-B112-93877BB62776}.Debug|Win32.Build.0 = Debug|Win32
+		{0178B127-6269-407D-B112-93877BB62776}.Debug|x64.ActiveCfg = Debug|x64
+		{0178B127-6269-407D-B112-93877BB62776}.Debug|x64.Build.0 = Debug|x64
+		{0178B127-6269-407D-B112-93877BB62776}.Release|Win32.ActiveCfg = Release|Win32
+		{0178B127-6269-407D-B112-93877BB62776}.Release|Win32.Build.0 = Release|Win32
+		{0178B127-6269-407D-B112-93877BB62776}.Release|x64.ActiveCfg = Release|x64
+		{0178B127-6269-407D-B112-93877BB62776}.Release|x64.Build.0 = Release|x64
+		{73632960-B3A6-464D-83A3-4B43365F19B8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{73632960-B3A6-464D-83A3-4B43365F19B8}.Debug|Win32.Build.0 = Debug|Win32
+		{73632960-B3A6-464D-83A3-4B43365F19B8}.Debug|x64.ActiveCfg = Debug|x64
+		{73632960-B3A6-464D-83A3-4B43365F19B8}.Debug|x64.Build.0 = Debug|x64
+		{73632960-B3A6-464D-83A3-4B43365F19B8}.Release|Win32.ActiveCfg = Release|Win32
+		{73632960-B3A6-464D-83A3-4B43365F19B8}.Release|Win32.Build.0 = Release|Win32
+		{73632960-B3A6-464D-83A3-4B43365F19B8}.Release|x64.ActiveCfg = Release|x64
+		{73632960-B3A6-464D-83A3-4B43365F19B8}.Release|x64.Build.0 = Release|x64
+		{C920062A-0647-4553-A3B2-37C58065664B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C920062A-0647-4553-A3B2-37C58065664B}.Debug|Win32.Build.0 = Debug|Win32
+		{C920062A-0647-4553-A3B2-37C58065664B}.Debug|x64.ActiveCfg = Debug|x64
+		{C920062A-0647-4553-A3B2-37C58065664B}.Debug|x64.Build.0 = Debug|x64
+		{C920062A-0647-4553-A3B2-37C58065664B}.Release|Win32.ActiveCfg = Release|Win32
+		{C920062A-0647-4553-A3B2-37C58065664B}.Release|Win32.Build.0 = Release|Win32
+		{C920062A-0647-4553-A3B2-37C58065664B}.Release|x64.ActiveCfg = Release|x64
+		{C920062A-0647-4553-A3B2-37C58065664B}.Release|x64.Build.0 = Release|x64
+		{37FC2C7F-1904-4811-8955-2F478830EAD1}.Debug|Win32.ActiveCfg = Debug|Win32
+		{37FC2C7F-1904-4811-8955-2F478830EAD1}.Debug|Win32.Build.0 = Debug|Win32
+		{37FC2C7F-1904-4811-8955-2F478830EAD1}.Debug|x64.ActiveCfg = Debug|x64
+		{37FC2C7F-1904-4811-8955-2F478830EAD1}.Debug|x64.Build.0 = Debug|x64
+		{37FC2C7F-1904-4811-8955-2F478830EAD1}.Release|Win32.ActiveCfg = Release|Win32
+		{37FC2C7F-1904-4811-8955-2F478830EAD1}.Release|Win32.Build.0 = Release|Win32
+		{37FC2C7F-1904-4811-8955-2F478830EAD1}.Release|x64.ActiveCfg = Release|x64
+		{37FC2C7F-1904-4811-8955-2F478830EAD1}.Release|x64.Build.0 = Release|x64
+		{F5AD9738-1A3D-4906-B9C4-A7D9CE33DC2C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{F5AD9738-1A3D-4906-B9C4-A7D9CE33DC2C}.Debug|Win32.Build.0 = Debug|Win32
+		{F5AD9738-1A3D-4906-B9C4-A7D9CE33DC2C}.Debug|x64.ActiveCfg = Debug|x64
+		{F5AD9738-1A3D-4906-B9C4-A7D9CE33DC2C}.Debug|x64.Build.0 = Debug|x64
+		{F5AD9738-1A3D-4906-B9C4-A7D9CE33DC2C}.Release|Win32.ActiveCfg = Release|Win32
+		{F5AD9738-1A3D-4906-B9C4-A7D9CE33DC2C}.Release|Win32.Build.0 = Release|Win32
+		{F5AD9738-1A3D-4906-B9C4-A7D9CE33DC2C}.Release|x64.ActiveCfg = Release|x64
+		{F5AD9738-1A3D-4906-B9C4-A7D9CE33DC2C}.Release|x64.Build.0 = Release|x64
+		{D9DF7F2F-93B7-4810-B5CD-96F4F33C079B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D9DF7F2F-93B7-4810-B5CD-96F4F33C079B}.Debug|Win32.Build.0 = Debug|Win32
+		{D9DF7F2F-93B7-4810-B5CD-96F4F33C079B}.Debug|x64.ActiveCfg = Debug|x64
+		{D9DF7F2F-93B7-4810-B5CD-96F4F33C079B}.Debug|x64.Build.0 = Debug|x64
+		{D9DF7F2F-93B7-4810-B5CD-96F4F33C079B}.Release|Win32.ActiveCfg = Release|Win32
+		{D9DF7F2F-93B7-4810-B5CD-96F4F33C079B}.Release|Win32.Build.0 = Release|Win32
+		{D9DF7F2F-93B7-4810-B5CD-96F4F33C079B}.Release|x64.ActiveCfg = Release|x64
+		{D9DF7F2F-93B7-4810-B5CD-96F4F33C079B}.Release|x64.Build.0 = Release|x64
+		{4C8454FE-81D3-4CA3-9927-29BA96F03DAC}.Debug|Win32.ActiveCfg = Debug|Win32
+		{4C8454FE-81D3-4CA3-9927-29BA96F03DAC}.Debug|Win32.Build.0 = Debug|Win32
+		{4C8454FE-81D3-4CA3-9927-29BA96F03DAC}.Debug|x64.ActiveCfg = Debug|x64
+		{4C8454FE-81D3-4CA3-9927-29BA96F03DAC}.Debug|x64.Build.0 = Debug|x64
+		{4C8454FE-81D3-4CA3-9927-29BA96F03DAC}.Release|Win32.ActiveCfg = Release|Win32
+		{4C8454FE-81D3-4CA3-9927-29BA96F03DAC}.Release|Win32.Build.0 = Release|Win32
+		{4C8454FE-81D3-4CA3-9927-29BA96F03DAC}.Release|x64.ActiveCfg = Release|x64
+		{4C8454FE-81D3-4CA3-9927-29BA96F03DAC}.Release|x64.Build.0 = Release|x64
+		{203EC78A-0531-43F0-A636-285439BDE025}.Debug|Win32.ActiveCfg = Debug|Win32
+		{203EC78A-0531-43F0-A636-285439BDE025}.Debug|Win32.Build.0 = Debug|Win32
+		{203EC78A-0531-43F0-A636-285439BDE025}.Debug|x64.ActiveCfg = Debug|x64
+		{203EC78A-0531-43F0-A636-285439BDE025}.Debug|x64.Build.0 = Debug|x64
+		{203EC78A-0531-43F0-A636-285439BDE025}.Release|Win32.ActiveCfg = Release|Win32
+		{203EC78A-0531-43F0-A636-285439BDE025}.Release|Win32.Build.0 = Release|Win32
+		{203EC78A-0531-43F0-A636-285439BDE025}.Release|x64.ActiveCfg = Release|x64
+		{203EC78A-0531-43F0-A636-285439BDE025}.Release|x64.Build.0 = Release|x64
+		{6B231032-3CB5-4EED-9210-810D666A23A0}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6B231032-3CB5-4EED-9210-810D666A23A0}.Debug|Win32.Build.0 = Debug|Win32
+		{6B231032-3CB5-4EED-9210-810D666A23A0}.Debug|x64.ActiveCfg = Debug|x64
+		{6B231032-3CB5-4EED-9210-810D666A23A0}.Debug|x64.Build.0 = Debug|x64
+		{6B231032-3CB5-4EED-9210-810D666A23A0}.Release|Win32.ActiveCfg = Release|Win32
+		{6B231032-3CB5-4EED-9210-810D666A23A0}.Release|Win32.Build.0 = Release|Win32
+		{6B231032-3CB5-4EED-9210-810D666A23A0}.Release|x64.ActiveCfg = Release|x64
+		{6B231032-3CB5-4EED-9210-810D666A23A0}.Release|x64.Build.0 = Release|x64
+		{DBA4088D-F6F9-4F8F-8820-082A4765C16C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{DBA4088D-F6F9-4F8F-8820-082A4765C16C}.Debug|Win32.Build.0 = Debug|Win32
+		{DBA4088D-F6F9-4F8F-8820-082A4765C16C}.Debug|x64.ActiveCfg = Debug|x64
+		{DBA4088D-F6F9-4F8F-8820-082A4765C16C}.Debug|x64.Build.0 = Debug|x64
+		{DBA4088D-F6F9-4F8F-8820-082A4765C16C}.Release|Win32.ActiveCfg = Release|Win32
+		{DBA4088D-F6F9-4F8F-8820-082A4765C16C}.Release|Win32.Build.0 = Release|Win32
+		{DBA4088D-F6F9-4F8F-8820-082A4765C16C}.Release|x64.ActiveCfg = Release|x64
+		{DBA4088D-F6F9-4F8F-8820-082A4765C16C}.Release|x64.Build.0 = Release|x64
+		{C2B04507-2521-4801-BF0D-5FD79D6D518C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C2B04507-2521-4801-BF0D-5FD79D6D518C}.Debug|Win32.Build.0 = Debug|Win32
+		{C2B04507-2521-4801-BF0D-5FD79D6D518C}.Debug|x64.ActiveCfg = Debug|x64
+		{C2B04507-2521-4801-BF0D-5FD79D6D518C}.Debug|x64.Build.0 = Debug|x64
+		{C2B04507-2521-4801-BF0D-5FD79D6D518C}.Release|Win32.ActiveCfg = Release|Win32
+		{C2B04507-2521-4801-BF0D-5FD79D6D518C}.Release|Win32.Build.0 = Release|Win32
+		{C2B04507-2521-4801-BF0D-5FD79D6D518C}.Release|x64.ActiveCfg = Release|x64
+		{C2B04507-2521-4801-BF0D-5FD79D6D518C}.Release|x64.Build.0 = Release|x64
+		{631C23CE-6C1D-4875-88F0-85E0A42B36EA}.Debug|Win32.ActiveCfg = Debug|Win32
+		{631C23CE-6C1D-4875-88F0-85E0A42B36EA}.Debug|Win32.Build.0 = Debug|Win32
+		{631C23CE-6C1D-4875-88F0-85E0A42B36EA}.Debug|x64.ActiveCfg = Debug|x64
+		{631C23CE-6C1D-4875-88F0-85E0A42B36EA}.Debug|x64.Build.0 = Debug|x64
+		{631C23CE-6C1D-4875-88F0-85E0A42B36EA}.Release|Win32.ActiveCfg = Release|Win32
+		{631C23CE-6C1D-4875-88F0-85E0A42B36EA}.Release|Win32.Build.0 = Release|Win32
+		{631C23CE-6C1D-4875-88F0-85E0A42B36EA}.Release|x64.ActiveCfg = Release|x64
+		{631C23CE-6C1D-4875-88F0-85E0A42B36EA}.Release|x64.Build.0 = Release|x64
+		{E4993E82-D68A-46CA-BAE0-9D35E172E46F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E4993E82-D68A-46CA-BAE0-9D35E172E46F}.Debug|Win32.Build.0 = Debug|Win32
+		{E4993E82-D68A-46CA-BAE0-9D35E172E46F}.Debug|x64.ActiveCfg = Debug|x64
+		{E4993E82-D68A-46CA-BAE0-9D35E172E46F}.Debug|x64.Build.0 = Debug|x64
+		{E4993E82-D68A-46CA-BAE0-9D35E172E46F}.Release|Win32.ActiveCfg = Release|Win32
+		{E4993E82-D68A-46CA-BAE0-9D35E172E46F}.Release|Win32.Build.0 = Release|Win32
+		{E4993E82-D68A-46CA-BAE0-9D35E172E46F}.Release|x64.ActiveCfg = Release|x64
+		{E4993E82-D68A-46CA-BAE0-9D35E172E46F}.Release|x64.Build.0 = Release|x64
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF62}.Debug|Win32.ActiveCfg = Debug|Win32
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF62}.Debug|Win32.Build.0 = Debug|Win32
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF62}.Debug|x64.ActiveCfg = Debug|x64
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF62}.Debug|x64.Build.0 = Debug|x64
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF62}.Release|Win32.ActiveCfg = Release|Win32
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF62}.Release|Win32.Build.0 = Release|Win32
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF62}.Release|x64.ActiveCfg = Release|x64
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF62}.Release|x64.Build.0 = Release|x64
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF61}.Debug|Win32.ActiveCfg = Debug|Win32
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF61}.Debug|Win32.Build.0 = Debug|Win32
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF61}.Debug|x64.ActiveCfg = Debug|x64
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF61}.Debug|x64.Build.0 = Debug|x64
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF61}.Release|Win32.ActiveCfg = Release|Win32
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF61}.Release|Win32.Build.0 = Release|Win32
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF61}.Release|x64.ActiveCfg = Release|x64
+		{DB312A49-12A9-4E07-9E96-451DC2D8FF61}.Release|x64.Build.0 = Release|x64
+		{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}.Debug|Win32.ActiveCfg = Debug|Win32
+		{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}.Debug|Win32.Build.0 = Debug|Win32
+		{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}.Debug|x64.ActiveCfg = Debug|x64
+		{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}.Debug|x64.Build.0 = Debug|x64
+		{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}.Release|Win32.ActiveCfg = Release|Win32
+		{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}.Release|Win32.Build.0 = Release|Win32
+		{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}.Release|x64.ActiveCfg = Release|x64
+		{62D4B15D-7A90-4ECB-BA19-5E021D6A21BC}.Release|x64.Build.0 = Release|x64
+		{9D4211F7-2C77-439C-82F0-30A4E43BA569}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9D4211F7-2C77-439C-82F0-30A4E43BA569}.Debug|Win32.Build.0 = Debug|Win32
+		{9D4211F7-2C77-439C-82F0-30A4E43BA569}.Debug|x64.ActiveCfg = Debug|x64
+		{9D4211F7-2C77-439C-82F0-30A4E43BA569}.Debug|x64.Build.0 = Debug|x64
+		{9D4211F7-2C77-439C-82F0-30A4E43BA569}.Release|Win32.ActiveCfg = Release|Win32
+		{9D4211F7-2C77-439C-82F0-30A4E43BA569}.Release|Win32.Build.0 = Release|Win32
+		{9D4211F7-2C77-439C-82F0-30A4E43BA569}.Release|x64.ActiveCfg = Release|x64
+		{9D4211F7-2C77-439C-82F0-30A4E43BA569}.Release|x64.Build.0 = Release|x64
+		{67351485-4D18-4245-BE39-A7EF0675ACD2}.Debug|Win32.ActiveCfg = Debug|Win32
+		{67351485-4D18-4245-BE39-A7EF0675ACD2}.Debug|Win32.Build.0 = Debug|Win32
+		{67351485-4D18-4245-BE39-A7EF0675ACD2}.Debug|x64.ActiveCfg = Debug|x64
+		{67351485-4D18-4245-BE39-A7EF0675ACD2}.Debug|x64.Build.0 = Debug|x64
+		{67351485-4D18-4245-BE39-A7EF0675ACD2}.Release|Win32.ActiveCfg = Release|Win32
+		{67351485-4D18-4245-BE39-A7EF0675ACD2}.Release|Win32.Build.0 = Release|Win32
+		{67351485-4D18-4245-BE39-A7EF0675ACD2}.Release|x64.ActiveCfg = Release|x64
+		{67351485-4D18-4245-BE39-A7EF0675ACD2}.Release|x64.Build.0 = Release|x64
+		{691EE0C0-DC57-4A48-8AEE-8ED75EB3A057}.Debug|Win32.ActiveCfg = Debug|Win32
+		{691EE0C0-DC57-4A48-8AEE-8ED75EB3A057}.Debug|Win32.Build.0 = Debug|Win32
+		{691EE0C0-DC57-4A48-8AEE-8ED75EB3A057}.Debug|x64.ActiveCfg = Debug|x64
+		{691EE0C0-DC57-4A48-8AEE-8ED75EB3A057}.Debug|x64.Build.0 = Debug|x64
+		{691EE0C0-DC57-4A48-8AEE-8ED75EB3A057}.Release|Win32.ActiveCfg = Release|Win32
+		{691EE0C0-DC57-4A48-8AEE-8ED75EB3A057}.Release|Win32.Build.0 = Release|Win32
+		{691EE0C0-DC57-4A48-8AEE-8ED75EB3A057}.Release|x64.ActiveCfg = Release|x64
+		{691EE0C0-DC57-4A48-8AEE-8ED75EB3A057}.Release|x64.Build.0 = Release|x64
+		{C7891A65-80AB-4245-912E-5F1E17B0E6C4}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C7891A65-80AB-4245-912E-5F1E17B0E6C4}.Debug|Win32.Build.0 = Debug|Win32
+		{C7891A65-80AB-4245-912E-5F1E17B0E6C4}.Debug|x64.ActiveCfg = Debug|x64
+		{C7891A65-80AB-4245-912E-5F1E17B0E6C4}.Debug|x64.Build.0 = Debug|x64
+		{C7891A65-80AB-4245-912E-5F1E17B0E6C4}.Release|Win32.ActiveCfg = Release|Win32
+		{C7891A65-80AB-4245-912E-5F1E17B0E6C4}.Release|Win32.Build.0 = Release|Win32
+		{C7891A65-80AB-4245-912E-5F1E17B0E6C4}.Release|x64.ActiveCfg = Release|x64
+		{C7891A65-80AB-4245-912E-5F1E17B0E6C4}.Release|x64.Build.0 = Release|x64
+		{E7611F49-F088-4175-9446-6111444E72C8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E7611F49-F088-4175-9446-6111444E72C8}.Debug|Win32.Build.0 = Debug|Win32
+		{E7611F49-F088-4175-9446-6111444E72C8}.Debug|x64.ActiveCfg = Debug|x64
+		{E7611F49-F088-4175-9446-6111444E72C8}.Debug|x64.Build.0 = Debug|x64
+		{E7611F49-F088-4175-9446-6111444E72C8}.Release|Win32.ActiveCfg = Release|Win32
+		{E7611F49-F088-4175-9446-6111444E72C8}.Release|Win32.Build.0 = Release|Win32
+		{E7611F49-F088-4175-9446-6111444E72C8}.Release|x64.ActiveCfg = Release|x64
+		{E7611F49-F088-4175-9446-6111444E72C8}.Release|x64.Build.0 = Release|x64
+		{659D0C08-D4ED-4BF3-B02B-2D8D4B5A7A7A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{659D0C08-D4ED-4BF3-B02B-2D8D4B5A7A7A}.Debug|Win32.Build.0 = Debug|Win32
+		{659D0C08-D4ED-4BF3-B02B-2D8D4B5A7A7A}.Debug|x64.ActiveCfg = Debug|x64
+		{659D0C08-D4ED-4BF3-B02B-2D8D4B5A7A7A}.Debug|x64.Build.0 = Debug|x64
+		{659D0C08-D4ED-4BF3-B02B-2D8D4B5A7A7A}.Release|Win32.ActiveCfg = Release|Win32
+		{659D0C08-D4ED-4BF3-B02B-2D8D4B5A7A7A}.Release|Win32.Build.0 = Release|Win32
+		{659D0C08-D4ED-4BF3-B02B-2D8D4B5A7A7A}.Release|x64.ActiveCfg = Release|x64
+		{659D0C08-D4ED-4BF3-B02B-2D8D4B5A7A7A}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(SubversionScc) = preSolution
+		Svn-Managed = True
+		Manager = AnkhSVN - Subversion Support for Visual Studio
+	EndGlobalSection
+EndGlobal
diff --git a/icu/source/common/Makefile.in b/icu/source/common/Makefile.in
new file mode 100644
index 0000000..51edd6f
--- /dev/null
+++ b/icu/source/common/Makefile.in
@@ -0,0 +1,210 @@
+#******************************************************************************
+#
+#   Copyright (C) 1999-2010, International Business Machines
+#   Corporation and others.  All Rights Reserved.
+#
+#******************************************************************************
+## Makefile.in for ICU - icuuc.so
+## Stephen F. Booth
+
+## Source directory information
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+
+top_builddir = ..
+
+## All the flags and other definitions are included here.
+include $(top_builddir)/icudefs.mk
+
+## Build directory information
+subdir = common
+
+# for service hook
+LOCALSVC_CPP=localsvc.cpp
+SVC_HOOK_INC=$(top_builddir)/common/svchook.mk
+
+## Extra files to remove for 'make clean'
+CLEANFILES = *~ $(DEPS) $(IMPORT_LIB) $(MIDDLE_IMPORT_LIB) $(FINAL_IMPORT_LIB) $(SVC_HOOK_INC)
+
+## Target information
+
+TARGET_STUBNAME=$(COMMON_STUBNAME)
+
+ifneq ($(ENABLE_STATIC),)
+TARGET = $(LIBDIR)/$(LIBSICU)$(TARGET_STUBNAME)$(ICULIBSUFFIX).$(A)
+endif
+
+ifneq ($(ENABLE_SHARED),)
+SO_TARGET = $(LIBDIR)/$(LIBICU)$(TARGET_STUBNAME)$(ICULIBSUFFIX).$(SO)
+ALL_SO_TARGETS = $(SO_TARGET) $(MIDDLE_SO_TARGET) $(FINAL_SO_TARGET) $(SHARED_OBJECT)
+
+ifeq ($(ENABLE_SO_VERSION_DATA),1)
+SO_VERSION_DATA = common.res
+endif
+
+ifeq ($(OS390BATCH),1)
+BATCH_TARGET = $(BATCH_COMMON_TARGET)
+BATCH_LIBS = $(BATCH_LIBICUDT) -lm
+endif   # OS390BATCH
+
+endif   # ENABLE_SHARED
+
+ALL_TARGETS = $(TARGET) $(ALL_SO_TARGETS) $(BATCH_TARGET)
+
+DYNAMICCPPFLAGS = $(SHAREDLIBCPPFLAGS)
+DYNAMICCFLAGS = $(SHAREDLIBCFLAGS)
+DYNAMICCXXFLAGS = $(SHAREDLIBCXXFLAGS)
+CFLAGS += $(LIBCFLAGS)
+CXXFLAGS += $(LIBCXXFLAGS)
+
+ifneq ($(top_builddir),$(top_srcdir))
+CPPFLAGS += -I$(top_builddir)/common
+endif
+CPPFLAGS += -I$(srcdir) -I$(top_srcdir)/i18n $(LIBCPPFLAGS) $(CPPFLAGSICUUC)
+# we want DEFS here, because we want icucfg.h
+DEFS += -DU_COMMON_IMPLEMENTATION @DEFS@ 
+LDFLAGS += $(LDFLAGSICUUC)
+
+# for plugin configuration
+CPPFLAGS += "-DDEFAULT_ICU_PLUGINS=\"$(libdir)/icu\" "
+
+# $(LIBICUDT) is either stub data or the real DLL common data.
+LIBS = $(LIBICUDT) $(DEFAULT_LIBS)
+
+OBJECTS = errorcode.o putil.o umath.o utypes.o uinvchar.o umutex.o ucln_cmn.o uinit.o uobject.o cmemory.o \
+udata.o ucmndata.o udatamem.o umapfile.o udataswp.o ucol_swp.o utrace.o \
+uhash.o uhash_us.o uenum.o ustrenum.o uvector.o ustack.o uvectr32.o uvectr64.o \
+ucnv.o ucnv_bld.o ucnv_cnv.o ucnv_io.o ucnv_cb.o ucnv_err.o ucnvlat1.o \
+ucnv_u7.o ucnv_u8.o ucnv_u16.o ucnv_u32.o ucnvscsu.o ucnvbocu.o \
+ucnv_ext.o ucnvmbcs.o ucnv2022.o ucnvhz.o ucnv_lmb.o ucnvisci.o ucnvdisp.o ucnv_set.o \
+uresbund.o ures_cnv.o uresdata.o resbund.o resbund_cnv.o \
+ucat.o locmap.o uloc.o locid.o locutil.o locavailable.o locdispnames.o loclikely.o locresdata.o \
+bytestream.o stringpiece.o \
+ustr_cnv.o unistr_cnv.o unistr.o unistr_case.o unistr_props.o \
+utf_impl.o ustring.o ustrcase.o ucasemap.o cstring.o ustrfmt.o ustrtrns.o ustr_wcs.o utext.o \
+normalizer2impl.o normalizer2.o filterednormalizer2.o normlzr.o unorm.o unormcmp.o unorm_it.o \
+chariter.o schriter.o uchriter.o uiter.o \
+uchar.o uprops.o ucase.o propname.o ubidi_props.o ubidi.o ubidiwrt.o ubidiln.o ushape.o \
+uscript.o usc_impl.o unames.o \
+utrie.o utrie2.o utrie2_builder.o bmpset.o unisetspan.o uset_props.o uniset_props.o uset.o uniset.o usetiter.o ruleiter.o caniter.o unifilt.o unifunct.o \
+uarrsort.o brkiter.o ubrk.o brkeng.o dictbe.o triedict.o \
+rbbi.o rbbidata.o rbbinode.o rbbirb.o rbbiscan.o rbbisetb.o rbbistbl.o rbbitblb.o \
+serv.o servnotf.o servls.o servlk.o servlkf.o servrbf.o servslkf.o \
+uidna.o usprep.o punycode.o \
+util.o util_props.o parsepos.o locbased.o cwchar.o wintz.o mutex.o dtintrv.o ucnvsel.o propsvec.o \
+ulist.o uloc_tag.o icudataver.o icuplug.o
+
+## Header files to install
+HEADERS = $(srcdir)/unicode/*.h unicode/*.h
+
+STATIC_OBJECTS = $(OBJECTS:.o=.$(STATIC_O))
+
+DEPS = $(OBJECTS:.o=.d)
+
+-include Makefile.local
+
+-include $(SVC_HOOK_INC)
+
+
+## List of phony targets
+.PHONY : all all-local install install-local clean clean-local	\
+distclean distclean-local install-library install-headers dist	\
+dist-local check check-local
+
+## Clear suffix list
+.SUFFIXES :
+
+## List of standard targets
+all: all-local
+install: install-local
+clean: clean-local
+distclean : distclean-local
+dist: dist-local
+check: all check-local
+
+all-local: $(ALL_TARGETS) unicode/platform.h
+
+install-local: install-headers install-library
+
+install-library: all-local
+	$(MKINSTALLDIRS) $(DESTDIR)$(libdir)
+ifneq ($(ENABLE_STATIC),)
+	$(INSTALL-L) $(TARGET) $(DESTDIR)$(libdir)
+endif
+ifneq ($(ENABLE_SHARED),)
+	$(INSTALL-L) $(FINAL_SO_TARGET) $(DESTDIR)$(libdir)
+ifneq ($(FINAL_SO_TARGET),$(SO_TARGET))
+	cd $(DESTDIR)$(libdir) && $(RM) $(notdir $(SO_TARGET)) && ln -s $(notdir $(FINAL_SO_TARGET)) $(notdir $(SO_TARGET))
+ifneq ($(FINAL_SO_TARGET),$(MIDDLE_SO_TARGET))
+	cd $(DESTDIR)$(libdir) && $(RM) $(notdir $(MIDDLE_SO_TARGET)) && ln -s $(notdir $(FINAL_SO_TARGET)) $(notdir $(MIDDLE_SO_TARGET))
+endif
+endif
+ifneq ($(IMPORT_LIB_EXT),)
+	$(INSTALL-L) $(FINAL_IMPORT_LIB) $(DESTDIR)$(libdir)
+ifneq ($(IMPORT_LIB),$(FINAL_IMPORT_LIB))
+	cd $(DESTDIR)$(libdir) && $(RM) $(notdir $(IMPORT_LIB)) && ln -s $(notdir $(FINAL_IMPORT_LIB)) $(notdir $(IMPORT_LIB))
+endif
+ifneq ($(MIDDLE_IMPORT_LIB),$(FINAL_IMPORT_LIB))
+	cd $(DESTDIR)$(libdir) && $(RM) $(notdir $(MIDDLE_IMPORT_LIB)) && ln -s $(notdir $(FINAL_IMPORT_LIB)) $(notdir $(MIDDLE_IMPORT_LIB))
+endif
+endif
+endif
+
+$(SVC_HOOK_INC):
+	@echo generating $@
+	@-test -f $(top_srcdir)/common/$(LOCALSVC_CPP) && ( echo "have $(LOCALSVC_CPP) - U_LOCAL_SERVICE_HOOK=1" ; \
+		echo 'CPPFLAGS +=-DU_LOCAL_SERVICE_HOOK=1' > $@ ; \
+		echo 'OBJECTS += $(LOCALSVC_CPP:%.cpp=%.o)' >> $@ \
+		 ) ; true
+	@echo "# Autogenerated by Makefile" >> $@
+
+install-headers:
+	$(MKINSTALLDIRS) $(DESTDIR)$(includedir)/unicode
+	@for file in $(HEADERS); do \
+	 echo "$(INSTALL_DATA) $$file $(DESTDIR)$(includedir)/unicode"; \
+	 $(INSTALL_DATA) $$file $(DESTDIR)$(includedir)/unicode || exit; \
+	done
+
+dist-local:
+
+clean-local:
+	test -z "$(CLEANFILES)" || $(RMV) $(CLEANFILES)
+	$(RMV) $(OBJECTS) $(STATIC_OBJECTS) $(ALL_TARGETS) $(SO_VERSION_DATA)
+
+distclean-local: clean-local
+	$(RMV) Makefile icucfg.h unicode/platform.h $(SVC_HOOK_INC)
+
+check-local:
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(SVC_HOOK_INC)
+	cd $(top_builddir) \
+	 && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+unicode/platform.h: $(srcdir)/unicode/platform.h.in $(top_builddir)/config.status
+	cd $(top_builddir) \
+	 && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+ifneq ($(ENABLE_STATIC),)
+$(TARGET): $(STATIC_OBJECTS)
+	$(AR) $(ARFLAGS) $(AR_OUTOPT)$@ $^
+	$(RANLIB) $@
+endif
+
+ifneq ($(ENABLE_SHARED),)
+$(SHARED_OBJECT): $(OBJECTS) $(SO_VERSION_DATA)
+	$(SHLIB.cc) $(LD_SONAME) $(OUTOPT)$@ $^ $(LIBS) -lgcc
+
+ifeq ($(OS390BATCH),1)
+$(BATCH_TARGET):$(OBJECTS)
+	$(SHLIB.cc) $(LD_SONAME) $(OUTOPT)$@ $^ $(BATCH_LIBS)
+endif   # OS390BATCH
+endif   # ENABLE_SHARED
+
+ifeq (,$(MAKECMDGOALS))
+-include $(DEPS)
+else
+ifneq ($(patsubst %clean,,$(MAKECMDGOALS)),)
+-include $(DEPS)
+endif
+endif
+
diff --git a/icu/source/common/bmpset.cpp b/icu/source/common/bmpset.cpp
new file mode 100644
index 0000000..db87c70
--- /dev/null
+++ b/icu/source/common/bmpset.cpp
@@ -0,0 +1,723 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 2007-2008, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*   file name:  bmpset.cpp
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2007jan29
+*   created by: Markus W. Scherer
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/uniset.h"
+#include "cmemory.h"
+#include "bmpset.h"
+
+U_NAMESPACE_BEGIN
+
+BMPSet::BMPSet(const int32_t *parentList, int32_t parentListLength) :
+        list(parentList), listLength(parentListLength) {
+    uprv_memset(asciiBytes, 0, sizeof(asciiBytes));
+    uprv_memset(table7FF, 0, sizeof(table7FF));
+    uprv_memset(bmpBlockBits, 0, sizeof(bmpBlockBits));
+
+    /*
+     * Set the list indexes for binary searches for
+     * U+0800, U+1000, U+2000, .., U+F000, U+10000.
+     * U+0800 is the first 3-byte-UTF-8 code point. Lower code points are
+     * looked up in the bit tables.
+     * The last pair of indexes is for finding supplementary code points.
+     */
+    list4kStarts[0]=findCodePoint(0x800, 0, listLength-1);
+    int32_t i;
+    for(i=1; i<=0x10; ++i) {
+        list4kStarts[i]=findCodePoint(i<<12, list4kStarts[i-1], listLength-1);
+    }
+    list4kStarts[0x11]=listLength-1;
+
+    initBits();
+    overrideIllegal();
+}
+
+BMPSet::BMPSet(const BMPSet &otherBMPSet, const int32_t *newParentList, int32_t newParentListLength) :
+        list(newParentList), listLength(newParentListLength) {
+    uprv_memcpy(asciiBytes, otherBMPSet.asciiBytes, sizeof(asciiBytes));
+    uprv_memcpy(table7FF, otherBMPSet.table7FF, sizeof(table7FF));
+    uprv_memcpy(bmpBlockBits, otherBMPSet.bmpBlockBits, sizeof(bmpBlockBits));
+    uprv_memcpy(list4kStarts, otherBMPSet.list4kStarts, sizeof(list4kStarts));
+}
+
+BMPSet::~BMPSet() {
+}
+
+/*
+ * Set bits in a bit rectangle in "vertical" bit organization.
+ * start<limit<=0x800
+ */
+static void set32x64Bits(uint32_t table[64], int32_t start, int32_t limit) {
+    int32_t lead=start>>6;
+    int32_t trail=start&0x3f;
+
+    // Set one bit indicating an all-one block.
+    uint32_t bits=(uint32_t)1<<lead;
+    if((start+1)==limit) {  // Single-character shortcut.
+        table[trail]|=bits;
+        return;
+    }
+
+    int32_t limitLead=limit>>6;
+    int32_t limitTrail=limit&0x3f;
+
+    if(lead==limitLead) {
+        // Partial vertical bit column.
+        while(trail<limitTrail) {
+            table[trail++]|=bits;
+        }
+    } else {
+        // Partial vertical bit column,
+        // followed by a bit rectangle,
+        // followed by another partial vertical bit column.
+        if(trail>0) {
+            do {
+                table[trail++]|=bits;
+            } while(trail<64);
+            ++lead;
+        }
+        if(lead<limitLead) {
+            bits=~((1<<lead)-1);
+            if(limitLead<0x20) {
+                bits&=(1<<limitLead)-1;
+            }
+            for(trail=0; trail<64; ++trail) {
+                table[trail]|=bits;
+            }
+        }
+        bits=1<<limitLead;
+        for(trail=0; trail<limitTrail; ++trail) {
+            table[trail]|=bits;
+        }
+    }
+}
+
+void BMPSet::initBits() {
+    UChar32 start, limit;
+    int32_t listIndex=0;
+
+    // Set asciiBytes[].
+    do {
+        start=list[listIndex++];
+        if(listIndex<listLength) {
+            limit=list[listIndex++];
+        } else {
+            limit=0x110000;
+        }
+        if(start>=0x80) {
+            break;
+        }
+        do {
+            asciiBytes[start++]=1;
+        } while(start<limit && start<0x80);
+    } while(limit<=0x80);
+
+    // Set table7FF[].
+    while(start<0x800) {
+        set32x64Bits(table7FF, start, limit<=0x800 ? limit : 0x800);
+        if(limit>0x800) {
+            start=0x800;
+            break;
+        }
+
+        start=list[listIndex++];
+        if(listIndex<listLength) {
+            limit=list[listIndex++];
+        } else {
+            limit=0x110000;
+        }
+    }
+
+    // Set bmpBlockBits[].
+    int32_t minStart=0x800;
+    while(start<0x10000) {
+        if(limit>0x10000) {
+            limit=0x10000;
+        }
+
+        if(start<minStart) {
+            start=minStart;
+        }
+        if(start<limit) {  // Else: Another range entirely in a known mixed-value block.
+            if(start&0x3f) {
+                // Mixed-value block of 64 code points.
+                start>>=6;
+                bmpBlockBits[start&0x3f]|=0x10001<<(start>>6);
+                start=(start+1)<<6;  // Round up to the next block boundary.
+                minStart=start;      // Ignore further ranges in this block.
+            }
+            if(start<limit) {
+                if(start<(limit&~0x3f)) {
+                    // Multiple all-ones blocks of 64 code points each.
+                    set32x64Bits(bmpBlockBits, start>>6, limit>>6);
+                }
+
+                if(limit&0x3f) {
+                    // Mixed-value block of 64 code points.
+                    limit>>=6;
+                    bmpBlockBits[limit&0x3f]|=0x10001<<(limit>>6);
+                    limit=(limit+1)<<6;  // Round up to the next block boundary.
+                    minStart=limit;      // Ignore further ranges in this block.
+                }
+            }
+        }
+
+        if(limit==0x10000) {
+            break;
+        }
+
+        start=list[listIndex++];
+        if(listIndex<listLength) {
+            limit=list[listIndex++];
+        } else {
+            limit=0x110000;
+        }
+    }
+}
+
+/*
+ * Override some bits and bytes to the result of contains(FFFD)
+ * for faster validity checking at runtime.
+ * No need to set 0 values where they were reset to 0 in the constructor
+ * and not modified by initBits().
+ * (asciiBytes[] trail bytes, table7FF[] 0..7F, bmpBlockBits[] 0..7FF)
+ * Need to set 0 values for surrogates D800..DFFF.
+ */
+void BMPSet::overrideIllegal() {
+    uint32_t bits, mask;
+    int32_t i;
+
+    if(containsSlow(0xfffd, list4kStarts[0xf], list4kStarts[0x10])) {
+        // contains(FFFD)==TRUE
+        for(i=0x80; i<0xc0; ++i) {
+            asciiBytes[i]=1;
+        }
+
+        bits=3;                 // Lead bytes 0xC0 and 0xC1.
+        for(i=0; i<64; ++i) {
+            table7FF[i]|=bits;
+        }
+
+        bits=1;                 // Lead byte 0xE0.
+        for(i=0; i<32; ++i) {   // First half of 4k block.
+            bmpBlockBits[i]|=bits;
+        }
+
+        mask=~(0x10001<<0xd);   // Lead byte 0xED.
+        bits=1<<0xd;
+        for(i=32; i<64; ++i) {  // Second half of 4k block.
+            bmpBlockBits[i]=(bmpBlockBits[i]&mask)|bits;
+        }
+    } else {
+        // contains(FFFD)==FALSE
+        mask=~(0x10001<<0xd);   // Lead byte 0xED.
+        for(i=32; i<64; ++i) {  // Second half of 4k block.
+            bmpBlockBits[i]&=mask;
+        }
+    }
+}
+
+int32_t BMPSet::findCodePoint(UChar32 c, int32_t lo, int32_t hi) const {
+    /* Examples:
+                                       findCodePoint(c)
+       set              list[]         c=0 1 3 4 7 8
+       ===              ==============   ===========
+       []               [110000]         0 0 0 0 0 0
+       [\u0000-\u0003]  [0, 4, 110000]   1 1 1 2 2 2
+       [\u0004-\u0007]  [4, 8, 110000]   0 0 0 1 1 2
+       [:Any:]          [0, 110000]      1 1 1 1 1 1
+     */
+
+    // Return the smallest i such that c < list[i].  Assume
+    // list[len - 1] == HIGH and that c is legal (0..HIGH-1).
+    if (c < list[lo])
+        return lo;
+    // High runner test.  c is often after the last range, so an
+    // initial check for this condition pays off.
+    if (lo >= hi || c >= list[hi-1])
+        return hi;
+    // invariant: c >= list[lo]
+    // invariant: c < list[hi]
+    for (;;) {
+        int32_t i = (lo + hi) >> 1;
+        if (i == lo) {
+            break; // Found!
+        } else if (c < list[i]) {
+            hi = i;
+        } else {
+            lo = i;
+        }
+    }
+    return hi;
+}
+
+UBool
+BMPSet::contains(UChar32 c) const {
+    if((uint32_t)c<=0x7f) {
+        return (UBool)asciiBytes[c];
+    } else if((uint32_t)c<=0x7ff) {
+        return (UBool)((table7FF[c&0x3f]&((uint32_t)1<<(c>>6)))!=0);
+    } else if((uint32_t)c<0xd800 || (c>=0xe000 && c<=0xffff)) {
+        int lead=c>>12;
+        uint32_t twoBits=(bmpBlockBits[(c>>6)&0x3f]>>lead)&0x10001;
+        if(twoBits<=1) {
+            // All 64 code points with the same bits 15..6
+            // are either in the set or not.
+            return (UBool)twoBits;
+        } else {
+            // Look up the code point in its 4k block of code points.
+            return containsSlow(c, list4kStarts[lead], list4kStarts[lead+1]);
+        }
+    } else if((uint32_t)c<=0x10ffff) {
+        // surrogate or supplementary code point
+        return containsSlow(c, list4kStarts[0xd], list4kStarts[0x11]);
+    } else {
+        // Out-of-range code points get FALSE, consistent with long-standing
+        // behavior of UnicodeSet::contains(c).
+        return FALSE;
+    }
+}
+
+/*
+ * Check for sufficient length for trail unit for each surrogate pair.
+ * Handle single surrogates as surrogate code points as usual in ICU.
+ */
+const UChar *
+BMPSet::span(const UChar *s, const UChar *limit, USetSpanCondition spanCondition) const {
+    UChar c, c2;
+
+    if(spanCondition) {
+        // span
+        do {
+            c=*s;
+            if(c<=0x7f) {
+                if(!asciiBytes[c]) {
+                    break;
+                }
+            } else if(c<=0x7ff) {
+                if((table7FF[c&0x3f]&((uint32_t)1<<(c>>6)))==0) {
+                    break;
+                }
+            } else if(c<0xd800 || c>=0xe000) {
+                int lead=c>>12;
+                uint32_t twoBits=(bmpBlockBits[(c>>6)&0x3f]>>lead)&0x10001;
+                if(twoBits<=1) {
+                    // All 64 code points with the same bits 15..6
+                    // are either in the set or not.
+                    if(twoBits==0) {
+                        break;
+                    }
+                } else {
+                    // Look up the code point in its 4k block of code points.
+                    if(!containsSlow(c, list4kStarts[lead], list4kStarts[lead+1])) {
+                        break;
+                    }
+                }
+            } else if(c>=0xdc00 || (s+1)==limit || (c2=s[1])<0xdc00 || c2>=0xe000) {
+                // surrogate code point
+                if(!containsSlow(c, list4kStarts[0xd], list4kStarts[0xe])) {
+                    break;
+                }
+            } else {
+                // surrogate pair
+                if(!containsSlow(U16_GET_SUPPLEMENTARY(c, c2), list4kStarts[0x10], list4kStarts[0x11])) {
+                    break;
+                }
+                ++s;
+            }
+        } while(++s<limit);
+    } else {
+        // span not
+        do {
+            c=*s;
+            if(c<=0x7f) {
+                if(asciiBytes[c]) {
+                    break;
+                }
+            } else if(c<=0x7ff) {
+                if((table7FF[c&0x3f]&((uint32_t)1<<(c>>6)))!=0) {
+                    break;
+                }
+            } else if(c<0xd800 || c>=0xe000) {
+                int lead=c>>12;
+                uint32_t twoBits=(bmpBlockBits[(c>>6)&0x3f]>>lead)&0x10001;
+                if(twoBits<=1) {
+                    // All 64 code points with the same bits 15..6
+                    // are either in the set or not.
+                    if(twoBits!=0) {
+                        break;
+                    }
+                } else {
+                    // Look up the code point in its 4k block of code points.
+                    if(containsSlow(c, list4kStarts[lead], list4kStarts[lead+1])) {
+                        break;
+                    }
+                }
+            } else if(c>=0xdc00 || (s+1)==limit || (c2=s[1])<0xdc00 || c2>=0xe000) {
+                // surrogate code point
+                if(containsSlow(c, list4kStarts[0xd], list4kStarts[0xe])) {
+                    break;
+                }
+            } else {
+                // surrogate pair
+                if(containsSlow(U16_GET_SUPPLEMENTARY(c, c2), list4kStarts[0x10], list4kStarts[0x11])) {
+                    break;
+                }
+                ++s;
+            }
+        } while(++s<limit);
+    }
+    return s;
+}
+
+/* Symmetrical with span(). */
+const UChar *
+BMPSet::spanBack(const UChar *s, const UChar *limit, USetSpanCondition spanCondition) const {
+    UChar c, c2;
+
+    if(spanCondition) {
+        // span
+        for(;;) {
+            c=*(--limit);
+            if(c<=0x7f) {
+                if(!asciiBytes[c]) {
+                    break;
+                }
+            } else if(c<=0x7ff) {
+                if((table7FF[c&0x3f]&((uint32_t)1<<(c>>6)))==0) {
+                    break;
+                }
+            } else if(c<0xd800 || c>=0xe000) {
+                int lead=c>>12;
+                uint32_t twoBits=(bmpBlockBits[(c>>6)&0x3f]>>lead)&0x10001;
+                if(twoBits<=1) {
+                    // All 64 code points with the same bits 15..6
+                    // are either in the set or not.
+                    if(twoBits==0) {
+                        break;
+                    }
+                } else {
+                    // Look up the code point in its 4k block of code points.
+                    if(!containsSlow(c, list4kStarts[lead], list4kStarts[lead+1])) {
+                        break;
+                    }
+                }
+            } else if(c<0xdc00 || s==limit || (c2=*(limit-1))<0xd800 || c2>=0xdc00) {
+                // surrogate code point
+                if(!containsSlow(c, list4kStarts[0xd], list4kStarts[0xe])) {
+                    break;
+                }
+            } else {
+                // surrogate pair
+                if(!containsSlow(U16_GET_SUPPLEMENTARY(c2, c), list4kStarts[0x10], list4kStarts[0x11])) {
+                    break;
+                }
+                --limit;
+            }
+            if(s==limit) {
+                return s;
+            }
+        }
+    } else {
+        // span not
+        for(;;) {
+            c=*(--limit);
+            if(c<=0x7f) {
+                if(asciiBytes[c]) {
+                    break;
+                }
+            } else if(c<=0x7ff) {
+                if((table7FF[c&0x3f]&((uint32_t)1<<(c>>6)))!=0) {
+                    break;
+                }
+            } else if(c<0xd800 || c>=0xe000) {
+                int lead=c>>12;
+                uint32_t twoBits=(bmpBlockBits[(c>>6)&0x3f]>>lead)&0x10001;
+                if(twoBits<=1) {
+                    // All 64 code points with the same bits 15..6
+                    // are either in the set or not.
+                    if(twoBits!=0) {
+                        break;
+                    }
+                } else {
+                    // Look up the code point in its 4k block of code points.
+                    if(containsSlow(c, list4kStarts[lead], list4kStarts[lead+1])) {
+                        break;
+                    }
+                }
+            } else if(c<0xdc00 || s==limit || (c2=*(limit-1))<0xd800 || c2>=0xdc00) {
+                // surrogate code point
+                if(containsSlow(c, list4kStarts[0xd], list4kStarts[0xe])) {
+                    break;
+                }
+            } else {
+                // surrogate pair
+                if(containsSlow(U16_GET_SUPPLEMENTARY(c2, c), list4kStarts[0x10], list4kStarts[0x11])) {
+                    break;
+                }
+                --limit;
+            }
+            if(s==limit) {
+                return s;
+            }
+        }
+    }
+    return limit+1;
+}
+
+/*
+ * Precheck for sufficient trail bytes at end of string only once per span.
+ * Check validity.
+ */
+const uint8_t *
+BMPSet::spanUTF8(const uint8_t *s, int32_t length, USetSpanCondition spanCondition) const {
+    const uint8_t *limit=s+length;
+    uint8_t b=*s;
+    if((int8_t)b>=0) {
+        // Initial all-ASCII span.
+        if(spanCondition) {
+            do {
+                if(!asciiBytes[b] || ++s==limit) {
+                    return s;
+                }
+                b=*s;
+            } while((int8_t)b>=0);
+        } else {
+            do {
+                if(asciiBytes[b] || ++s==limit) {
+                    return s;
+                }
+                b=*s;
+            } while((int8_t)b>=0);
+        }
+        length=(int32_t)(limit-s);
+    }
+
+    if(spanCondition!=USET_SPAN_NOT_CONTAINED) {
+        spanCondition=USET_SPAN_CONTAINED;  // Pin to 0/1 values.
+    }
+
+    const uint8_t *limit0=limit;
+
+    /*
+     * Make sure that the last 1/2/3/4-byte sequence before limit is complete
+     * or runs into a lead byte.
+     * In the span loop compare s with limit only once
+     * per multi-byte character.
+     *
+     * Give a trailing illegal sequence the same value as the result of contains(FFFD),
+     * including it if that is part of the span, otherwise set limit0 to before
+     * the truncated sequence.
+     */
+    b=*(limit-1);
+    if((int8_t)b<0) {
+        // b>=0x80: lead or trail byte
+        if(b<0xc0) {
+            // single trail byte, check for preceding 3- or 4-byte lead byte
+            if(length>=2 && (b=*(limit-2))>=0xe0) {
+                limit-=2;
+                if(asciiBytes[0x80]!=spanCondition) {
+                    limit0=limit;
+                }
+            } else if(b<0xc0 && b>=0x80 && length>=3 && (b=*(limit-3))>=0xf0) {
+                // 4-byte lead byte with only two trail bytes
+                limit-=3;
+                if(asciiBytes[0x80]!=spanCondition) {
+                    limit0=limit;
+                }
+            }
+        } else {
+            // lead byte with no trail bytes
+            --limit;
+            if(asciiBytes[0x80]!=spanCondition) {
+                limit0=limit;
+            }
+        }
+    }
+
+    uint8_t t1, t2, t3;
+
+    while(s<limit) {
+        b=*s;
+        if(b<0xc0) {
+            // ASCII; or trail bytes with the result of contains(FFFD).
+            if(spanCondition) {
+                do {
+                    if(!asciiBytes[b]) {
+                        return s;
+                    } else if(++s==limit) {
+                        return limit0;
+                    }
+                    b=*s;
+                } while(b<0xc0);
+            } else {
+                do {
+                    if(asciiBytes[b]) {
+                        return s;
+                    } else if(++s==limit) {
+                        return limit0;
+                    }
+                    b=*s;
+                } while(b<0xc0);
+            }
+        }
+        ++s;  // Advance past the lead byte.
+        if(b>=0xe0) {
+            if(b<0xf0) {
+                if( /* handle U+0000..U+FFFF inline */
+                    (t1=(uint8_t)(s[0]-0x80)) <= 0x3f &&
+                    (t2=(uint8_t)(s[1]-0x80)) <= 0x3f
+                ) {
+                    b&=0xf;
+                    uint32_t twoBits=(bmpBlockBits[t1]>>b)&0x10001;
+                    if(twoBits<=1) {
+                        // All 64 code points with this lead byte and middle trail byte
+                        // are either in the set or not.
+                        if(twoBits!=(uint32_t)spanCondition) {
+                            return s-1;
+                        }
+                    } else {
+                        // Look up the code point in its 4k block of code points.
+                        UChar32 c=(b<<12)|(t1<<6)|t2;
+                        if(containsSlow(c, list4kStarts[b], list4kStarts[b+1]) != spanCondition) {
+                            return s-1;
+                        }
+                    }
+                    s+=2;
+                    continue;
+                }
+            } else if( /* handle U+10000..U+10FFFF inline */
+                (t1=(uint8_t)(s[0]-0x80)) <= 0x3f &&
+                (t2=(uint8_t)(s[1]-0x80)) <= 0x3f &&
+                (t3=(uint8_t)(s[2]-0x80)) <= 0x3f
+            ) {
+                // Give an illegal sequence the same value as the result of contains(FFFD).
+                UChar32 c=((UChar32)(b-0xf0)<<18)|((UChar32)t1<<12)|(t2<<6)|t3;
+                if( (   (0x10000<=c && c<=0x10ffff) ?
+                            containsSlow(c, list4kStarts[0x10], list4kStarts[0x11]) :
+                            asciiBytes[0x80]
+                    ) != spanCondition
+                ) {
+                    return s-1;
+                }
+                s+=3;
+                continue;
+            }
+        } else /* 0xc0<=b<0xe0 */ {
+            if( /* handle U+0000..U+07FF inline */
+                (t1=(uint8_t)(*s-0x80)) <= 0x3f
+            ) {
+                if((USetSpanCondition)((table7FF[t1]&((uint32_t)1<<(b&0x1f)))!=0) != spanCondition) {
+                    return s-1;
+                }
+                ++s;
+                continue;
+            }
+        }
+
+        // Give an illegal sequence the same value as the result of contains(FFFD).
+        // Handle each byte of an illegal sequence separately to simplify the code;
+        // no need to optimize error handling.
+        if(asciiBytes[0x80]!=spanCondition) {
+            return s-1;
+        }
+    }
+
+    return limit0;
+}
+
+/*
+ * While going backwards through UTF-8 optimize only for ASCII.
+ * Unlike UTF-16, UTF-8 is not forward-backward symmetrical, that is, it is not
+ * possible to tell from the last byte in a multi-byte sequence how many
+ * preceding bytes there should be. Therefore, going backwards through UTF-8
+ * is much harder than going forward.
+ */
+int32_t
+BMPSet::spanBackUTF8(const uint8_t *s, int32_t length, USetSpanCondition spanCondition) const {
+    if(spanCondition!=USET_SPAN_NOT_CONTAINED) {
+        spanCondition=USET_SPAN_CONTAINED;  // Pin to 0/1 values.
+    }
+
+    uint8_t b;
+
+    do {
+        b=s[--length];
+        if((int8_t)b>=0) {
+            // ASCII sub-span
+            if(spanCondition) {
+                do {
+                    if(!asciiBytes[b]) {
+                        return length+1;
+                    } else if(length==0) {
+                        return 0;
+                    }
+                    b=s[--length];
+                } while((int8_t)b>=0);
+            } else {
+                do {
+                    if(asciiBytes[b]) {
+                        return length+1;
+                    } else if(length==0) {
+                        return 0;
+                    }
+                    b=s[--length];
+                } while((int8_t)b>=0);
+            }
+        }
+
+        int32_t prev=length;
+        UChar32 c;
+        if(b<0xc0) {
+            // trail byte: collect a multi-byte character
+            c=utf8_prevCharSafeBody(s, 0, &length, b, -1);
+            if(c<0) {
+                c=0xfffd;
+            }
+        } else {
+            // lead byte in last-trail position
+            c=0xfffd;
+        }
+        // c is a valid code point, not ASCII, not a surrogate
+        if(c<=0x7ff) {
+            if((USetSpanCondition)((table7FF[c&0x3f]&((uint32_t)1<<(c>>6)))!=0) != spanCondition) {
+                return prev+1;
+            }
+        } else if(c<=0xffff) {
+            int lead=c>>12;
+            uint32_t twoBits=(bmpBlockBits[(c>>6)&0x3f]>>lead)&0x10001;
+            if(twoBits<=1) {
+                // All 64 code points with the same bits 15..6
+                // are either in the set or not.
+                if(twoBits!=(uint32_t)spanCondition) {
+                    return prev+1;
+                }
+            } else {
+                // Look up the code point in its 4k block of code points.
+                if(containsSlow(c, list4kStarts[lead], list4kStarts[lead+1]) != spanCondition) {
+                    return prev+1;
+                }
+            }
+        } else {
+            if(containsSlow(c, list4kStarts[0x10], list4kStarts[0x11]) != spanCondition) {
+                return prev+1;
+            }
+        }
+    } while(length>0);
+    return 0;
+}
+
+U_NAMESPACE_END
diff --git a/icu/source/common/bmpset.h b/icu/source/common/bmpset.h
new file mode 100644
index 0000000..d9e08ea
--- /dev/null
+++ b/icu/source/common/bmpset.h
@@ -0,0 +1,161 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 2007, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*   file name:  bmpset.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2007jan29
+*   created by: Markus W. Scherer
+*/
+
+#ifndef __BMPSET_H__
+#define __BMPSET_H__
+
+#include "unicode/utypes.h"
+#include "unicode/uniset.h"
+
+U_NAMESPACE_BEGIN
+
+/*
+ * Helper class for frozen UnicodeSets, implements contains() and span()
+ * optimized for BMP code points. Structured to be UTF-8-friendly.
+ *
+ * ASCII: Look up bytes.
+ * 2-byte characters: Bits organized vertically.
+ * 3-byte characters: Use zero/one/mixed data per 64-block in U+0000..U+FFFF,
+ *                    with mixed for illegal ranges.
+ * Supplementary characters: Call contains() on the parent set.
+ */
+class BMPSet : public UMemory {
+public:
+    BMPSet(const int32_t *parentList, int32_t parentListLength);
+    BMPSet(const BMPSet &otherBMPSet, const int32_t *newParentList, int32_t newParentListLength);
+    virtual ~BMPSet();
+
+    virtual UBool contains(UChar32 c) const;
+
+    /*
+     * Span the initial substring for which each character c has spanCondition==contains(c).
+     * It must be s<limit and spanCondition==0 or 1.
+     * @return The string pointer which limits the span.
+     */
+    const UChar *span(const UChar *s, const UChar *limit, USetSpanCondition spanCondition) const;
+
+    /*
+     * Span the trailing substring for which each character c has spanCondition==contains(c).
+     * It must be s<limit and spanCondition==0 or 1.
+     * @return The string pointer which starts the span.
+     */
+    const UChar *spanBack(const UChar *s, const UChar *limit, USetSpanCondition spanCondition) const;
+
+    /*
+     * Span the initial substring for which each character c has spanCondition==contains(c).
+     * It must be length>0 and spanCondition==0 or 1.
+     * @return The string pointer which limits the span.
+     */
+    const uint8_t *spanUTF8(const uint8_t *s, int32_t length, USetSpanCondition spanCondition) const;
+
+    /*
+     * Span the trailing substring for which each character c has spanCondition==contains(c).
+     * It must be length>0 and spanCondition==0 or 1.
+     * @return The start of the span.
+     */
+    int32_t spanBackUTF8(const uint8_t *s, int32_t length, USetSpanCondition spanCondition) const;
+
+private:
+    void initBits();
+    void overrideIllegal();
+
+    /**
+     * Same as UnicodeSet::findCodePoint(UChar32 c) const except that the
+     * binary search is restricted for finding code points in a certain range.
+     *
+     * For restricting the search for finding in the range start..end,
+     * pass in
+     *   lo=findCodePoint(start) and
+     *   hi=findCodePoint(end)
+     * with 0<=lo<=hi<len.
+     * findCodePoint(c) defaults to lo=0 and hi=len-1.
+     *
+     * @param c a character in a subrange of MIN_VALUE..MAX_VALUE
+     * @param lo The lowest index to be returned.
+     * @param hi The highest index to be returned.
+     * @return the smallest integer i in the range lo..hi,
+     *         inclusive, such that c < list[i]
+     */
+    int32_t findCodePoint(UChar32 c, int32_t lo, int32_t hi) const;
+
+    inline UBool containsSlow(UChar32 c, int32_t lo, int32_t hi) const;
+
+    /*
+     * One byte per ASCII character, or trail byte in lead position.
+     * 0 or 1 for ASCII characters.
+     * The value for trail bytes is the result of contains(FFFD)
+     * for faster validity checking at runtime.
+     */
+    UBool asciiBytes[0xc0];
+
+    /*
+     * One bit per code point from U+0000..U+07FF.
+     * The bits are organized vertically; consecutive code points
+     * correspond to the same bit positions in consecutive table words.
+     * With code point parts
+     *   lead=c{10..6}
+     *   trail=c{5..0}
+     * it is set.contains(c)==(table7FF[trail] bit lead)
+     *
+     * Bits for 0..7F (non-shortest forms) are set to the result of contains(FFFD)
+     * for faster validity checking at runtime.
+     */
+    uint32_t table7FF[64];
+
+    /*
+     * One bit per 64 BMP code points.
+     * The bits are organized vertically; consecutive 64-code point blocks
+     * correspond to the same bit position in consecutive table words.
+     * With code point parts
+     *   lead=c{15..12}
+     *   t1=c{11..6}
+     * test bits (lead+16) and lead in bmpBlockBits[t1].
+     * If the upper bit is 0, then the lower bit indicates if contains(c)
+     * for all code points in the 64-block.
+     * If the upper bit is 1, then the block is mixed and set.contains(c)
+     * must be called.
+     *
+     * Bits for 0..7FF (non-shortest forms) and D800..DFFF are set to
+     * the result of contains(FFFD) for faster validity checking at runtime.
+     */
+    uint32_t bmpBlockBits[64];
+
+    /*
+     * Inversion list indexes for restricted binary searches in
+     * findCodePoint(), from
+     * findCodePoint(U+0800, U+1000, U+2000, .., U+F000, U+10000).
+     * U+0800 is the first 3-byte-UTF-8 code point. Code points below U+0800 are
+     * always looked up in the bit tables.
+     * The last pair of indexes is for finding supplementary code points.
+     */
+    int32_t list4kStarts[18];
+
+    /*
+     * The inversion list of the parent set, for the slower contains() implementation
+     * for mixed BMP blocks and for supplementary code points.
+     * The list is terminated with list[listLength-1]=0x110000.
+     */
+    const int32_t *list;
+    int32_t listLength;
+};
+
+inline UBool BMPSet::containsSlow(UChar32 c, int32_t lo, int32_t hi) const {
+    return (UBool)(findCodePoint(c, lo, hi) & 1);
+}
+
+U_NAMESPACE_END
+
+#endif
diff --git a/icu/source/common/brkeng.cpp b/icu/source/common/brkeng.cpp
new file mode 100644
index 0000000..6d1fa36
--- /dev/null
+++ b/icu/source/common/brkeng.cpp
@@ -0,0 +1,290 @@
+/**
+ ************************************************************************************
+ * Copyright (C) 2006-2009, International Business Machines Corporation and others. *
+ * All Rights Reserved.                                                             *
+ ************************************************************************************
+ */
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "brkeng.h"
+#include "dictbe.h"
+#include "triedict.h"
+#include "unicode/uchar.h"
+#include "unicode/uniset.h"
+#include "unicode/chariter.h"
+#include "unicode/ures.h"
+#include "unicode/udata.h"
+#include "unicode/putil.h"
+#include "unicode/ustring.h"
+#include "unicode/uscript.h"
+#include "uvector.h"
+#include "umutex.h"
+#include "uresimp.h"
+#include "ubrkimpl.h"
+
+U_NAMESPACE_BEGIN
+
+/*
+ ******************************************************************
+ */
+
+LanguageBreakEngine::LanguageBreakEngine() {
+}
+
+LanguageBreakEngine::~LanguageBreakEngine() {
+}
+
+/*
+ ******************************************************************
+ */
+
+LanguageBreakFactory::LanguageBreakFactory() {
+}
+
+LanguageBreakFactory::~LanguageBreakFactory() {
+}
+
+/*
+ ******************************************************************
+ */
+
+UnhandledEngine::UnhandledEngine(UErrorCode &/*status*/) {
+    for (int32_t i = 0; i < (int32_t)(sizeof(fHandled)/sizeof(fHandled[0])); ++i) {
+        fHandled[i] = 0;
+    }
+}
+
+UnhandledEngine::~UnhandledEngine() {
+    for (int32_t i = 0; i < (int32_t)(sizeof(fHandled)/sizeof(fHandled[0])); ++i) {
+        if (fHandled[i] != 0) {
+            delete fHandled[i];
+        }
+    }
+}
+
+UBool
+UnhandledEngine::handles(UChar32 c, int32_t breakType) const {
+    return (breakType >= 0 && breakType < (int32_t)(sizeof(fHandled)/sizeof(fHandled[0]))
+        && fHandled[breakType] != 0 && fHandled[breakType]->contains(c));
+}
+
+int32_t
+UnhandledEngine::findBreaks( UText *text,
+                                 int32_t startPos,
+                                 int32_t endPos,
+                                 UBool reverse,
+                                 int32_t breakType,
+                                 UStack &/*foundBreaks*/ ) const {
+    if (breakType >= 0 && breakType < (int32_t)(sizeof(fHandled)/sizeof(fHandled[0]))) {
+        UChar32 c = utext_current32(text); 
+        if (reverse) {
+            while((int32_t)utext_getNativeIndex(text) > startPos && fHandled[breakType]->contains(c)) {
+                c = utext_previous32(text);
+            }
+        }
+        else {
+            while((int32_t)utext_getNativeIndex(text) < endPos && fHandled[breakType]->contains(c)) {
+                utext_next32(text);            // TODO:  recast loop to work with post-increment operations.
+                c = utext_current32(text);
+            }
+        }
+    }
+    return 0;
+}
+
+void
+UnhandledEngine::handleCharacter(UChar32 c, int32_t breakType) {
+    if (breakType >= 0 && breakType < (int32_t)(sizeof(fHandled)/sizeof(fHandled[0]))) {
+        if (fHandled[breakType] == 0) {
+            fHandled[breakType] = new UnicodeSet();
+            if (fHandled[breakType] == 0) {
+                return;
+            }
+        }
+        if (!fHandled[breakType]->contains(c)) {
+            UErrorCode status = U_ZERO_ERROR;
+            // Apply the entire script of the character.
+            int32_t script = u_getIntPropertyValue(c, UCHAR_SCRIPT);
+            fHandled[breakType]->applyIntPropertyValue(UCHAR_SCRIPT, script, status);
+        }
+    }
+}
+
+/*
+ ******************************************************************
+ */
+
+ICULanguageBreakFactory::ICULanguageBreakFactory(UErrorCode &/*status*/) {
+    fEngines = 0;
+}
+
+ICULanguageBreakFactory::~ICULanguageBreakFactory() {
+    if (fEngines != 0) {
+        delete fEngines;
+    }
+}
+
+U_NAMESPACE_END
+U_CDECL_BEGIN
+static void U_CALLCONV _deleteEngine(void *obj) {
+    delete (const U_NAMESPACE_QUALIFIER LanguageBreakEngine *) obj;
+}
+U_CDECL_END
+U_NAMESPACE_BEGIN
+
+const LanguageBreakEngine *
+ICULanguageBreakFactory::getEngineFor(UChar32 c, int32_t breakType) {
+    UBool       needsInit;
+    int32_t     i;
+    const LanguageBreakEngine *lbe = NULL;
+    UErrorCode  status = U_ZERO_ERROR;
+
+    // TODO: The global mutex should not be used.
+    // The global mutex should only be used for short periods.
+    // A ICULanguageBreakFactory specific mutex should be used.
+    umtx_lock(NULL);
+    needsInit = (UBool)(fEngines == NULL);
+    if (!needsInit) {
+        i = fEngines->size();
+        while (--i >= 0) {
+            lbe = (const LanguageBreakEngine *)(fEngines->elementAt(i));
+            if (lbe != NULL && lbe->handles(c, breakType)) {
+                break;
+            }
+            lbe = NULL;
+        }
+    }
+    umtx_unlock(NULL);
+    
+    if (lbe != NULL) {
+        return lbe;
+    }
+    
+    if (needsInit) {
+        UStack  *engines = new UStack(_deleteEngine, NULL, status);
+        if (U_SUCCESS(status) && engines == NULL) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+        }
+        else if (U_FAILURE(status)) {
+            delete engines;
+            engines = NULL;
+        }
+        else {
+            umtx_lock(NULL);
+            if (fEngines == NULL) {
+                fEngines = engines;
+                engines = NULL;
+            }
+            umtx_unlock(NULL);
+            delete engines;
+        }
+    }
+    
+    if (fEngines == NULL) {
+        return NULL;
+    }
+
+    // We didn't find an engine the first time through, or there was no
+    // stack. Create an engine.
+    const LanguageBreakEngine *newlbe = loadEngineFor(c, breakType);
+    
+    // Now get the lock, and see if someone else has created it in the
+    // meantime
+    umtx_lock(NULL);
+    i = fEngines->size();
+    while (--i >= 0) {
+        lbe = (const LanguageBreakEngine *)(fEngines->elementAt(i));
+        if (lbe != NULL && lbe->handles(c, breakType)) {
+            break;
+        }
+        lbe = NULL;
+    }
+    if (lbe == NULL && newlbe != NULL) {
+        fEngines->push((void *)newlbe, status);
+        lbe = newlbe;
+        newlbe = NULL;
+    }
+    umtx_unlock(NULL);
+    
+    delete newlbe;
+
+    return lbe;
+}
+
+const LanguageBreakEngine *
+ICULanguageBreakFactory::loadEngineFor(UChar32 c, int32_t breakType) {
+    UErrorCode status = U_ZERO_ERROR;
+    UScriptCode code = uscript_getScript(c, &status);
+    if (U_SUCCESS(status)) {
+        const CompactTrieDictionary *dict = loadDictionaryFor(code, breakType);
+        if (dict != NULL) {
+            const LanguageBreakEngine *engine = NULL;
+            switch(code) {
+            case USCRIPT_THAI:
+                engine = new ThaiBreakEngine(dict, status);
+                break;
+            default:
+                break;
+            }
+            if (engine == NULL) {
+                delete dict;
+            }
+            else if (U_FAILURE(status)) {
+                delete engine;
+                engine = NULL;
+            }
+            return engine;
+        }
+    }
+    return NULL;
+}
+
+const CompactTrieDictionary *
+ICULanguageBreakFactory::loadDictionaryFor(UScriptCode script, int32_t /*breakType*/) {
+    UErrorCode status = U_ZERO_ERROR;
+    // Open root from brkitr tree.
+    char dictnbuff[256];
+    char ext[4]={'\0'};
+
+    UResourceBundle *b = ures_open(U_ICUDATA_BRKITR, "", &status);
+    b = ures_getByKeyWithFallback(b, "dictionaries", b, &status);
+    b = ures_getByKeyWithFallback(b, uscript_getShortName(script), b, &status);
+    int32_t dictnlength = 0;
+    const UChar *dictfname = ures_getString(b, &dictnlength, &status);
+    if (U_SUCCESS(status) && (size_t)dictnlength >= sizeof(dictnbuff)) {
+        dictnlength = 0;
+        status = U_BUFFER_OVERFLOW_ERROR;
+    }
+    if (U_SUCCESS(status) && dictfname) {
+        UChar* extStart=u_strchr(dictfname, 0x002e);
+        int len = 0;
+        if(extStart!=NULL){
+            len = (int)(extStart-dictfname);
+            u_UCharsToChars(extStart+1, ext, sizeof(ext)); // nul terminates the buff
+            u_UCharsToChars(dictfname, dictnbuff, len);
+        }
+        dictnbuff[len]=0; // nul terminate
+    }
+    ures_close(b);
+    UDataMemory *file = udata_open(U_ICUDATA_BRKITR, ext, dictnbuff, &status);
+    if (U_SUCCESS(status)) {
+        const CompactTrieDictionary *dict = new CompactTrieDictionary(
+            file, status);
+        if (U_SUCCESS(status) && dict == NULL) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+        }
+        if (U_FAILURE(status)) {
+            delete dict;
+            dict = NULL;
+        }
+        return dict;
+    }
+    return NULL;
+}
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/icu/source/common/brkeng.h b/icu/source/common/brkeng.h
new file mode 100644
index 0000000..618b2ae
--- /dev/null
+++ b/icu/source/common/brkeng.h
@@ -0,0 +1,292 @@
+/**
+ ************************************************************************************
+ * Copyright (C) 2006-2007, International Business Machines Corporation and others. *
+ * All Rights Reserved.                                                             *
+ ************************************************************************************
+ */
+
+#ifndef BRKENG_H
+#define BRKENG_H
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+#include "unicode/utext.h"
+#include "unicode/uscript.h"
+
+U_NAMESPACE_BEGIN
+
+class UnicodeSet;
+class UStack;
+class CompactTrieDictionary;
+
+/*******************************************************************
+ * LanguageBreakEngine
+ */
+
+/**
+ * <p>LanguageBreakEngines implement language-specific knowledge for
+ * finding text boundaries within a run of characters belonging to a
+ * specific set. The boundaries will be of a specific kind, e.g. word,
+ * line, etc.</p>
+ *
+ * <p>LanguageBreakEngines should normally be implemented so as to
+ * be shared between threads without locking.</p>
+ */
+class LanguageBreakEngine : public UMemory {
+ public:
+
+  /**
+   * <p>Default constructor.</p>
+   *
+   */
+  LanguageBreakEngine();
+
+  /**
+   * <p>Virtual destructor.</p>
+   */
+  virtual ~LanguageBreakEngine();
+
+ /**
+  * <p>Indicate whether this engine handles a particular character for
+  * a particular kind of break.</p>
+  *
+  * @param c A character which begins a run that the engine might handle
+  * @param breakType The type of text break which the caller wants to determine
+  * @return TRUE if this engine handles the particular character and break
+  * type.
+  */
+  virtual UBool handles(UChar32 c, int32_t breakType) const = 0;
+
+ /**
+  * <p>Find any breaks within a run in the supplied text.</p>
+  *
+  * @param text A UText representing the text. The
+  * iterator is left at the end of the run of characters which the engine
+  * is capable of handling.
+  * @param startPos The start of the run within the supplied text.
+  * @param endPos The end of the run within the supplied text.
+  * @param reverse Whether the caller is looking for breaks in a reverse
+  * direction.
+  * @param breakType The type of break desired, or -1.
+  * @param foundBreaks An allocated C array of the breaks found, if any
+  * @return The number of breaks found.
+  */
+  virtual int32_t findBreaks( UText *text,
+                              int32_t startPos,
+                              int32_t endPos,
+                              UBool reverse,
+                              int32_t breakType,
+                              UStack &foundBreaks ) const = 0;
+
+};
+
+/*******************************************************************
+ * LanguageBreakFactory
+ */
+
+/**
+ * <p>LanguageBreakFactorys find and return a LanguageBreakEngine
+ * that can determine breaks for characters in a specific set, if
+ * such an object can be found.</p>
+ *
+ * <p>If a LanguageBreakFactory is to be shared between threads,
+ * appropriate synchronization must be used; there is none internal
+ * to the factory.</p>
+ *
+ * <p>A LanguageBreakEngine returned by a LanguageBreakFactory can
+ * normally be shared between threads without synchronization, unless
+ * the specific subclass of LanguageBreakFactory indicates otherwise.</p>
+ *
+ * <p>A LanguageBreakFactory is responsible for deleting any LanguageBreakEngine
+ * it returns when it itself is deleted, unless the specific subclass of
+ * LanguageBreakFactory indicates otherwise. Naturally, the factory should
+ * not be deleted until the LanguageBreakEngines it has returned are no
+ * longer needed.</p>
+ */
+class LanguageBreakFactory : public UMemory {
+ public:
+
+  /**
+   * <p>Default constructor.</p>
+   *
+   */
+  LanguageBreakFactory();
+
+  /**
+   * <p>Virtual destructor.</p>
+   */
+  virtual ~LanguageBreakFactory();
+
+ /**
+  * <p>Find and return a LanguageBreakEngine that can find the desired
+  * kind of break for the set of characters to which the supplied
+  * character belongs. It is up to the set of available engines to
+  * determine what the sets of characters are.</p>
+  *
+  * @param c A character that begins a run for which a LanguageBreakEngine is
+  * sought.
+  * @param breakType The kind of text break for which a LanguageBreakEngine is
+  * sought.
+  * @return A LanguageBreakEngine with the desired characteristics, or 0.
+  */
+  virtual const LanguageBreakEngine *getEngineFor(UChar32 c, int32_t breakType) = 0;
+
+};
+
+/*******************************************************************
+ * UnhandledEngine
+ */
+
+/**
+ * <p>UnhandledEngine is a special subclass of LanguageBreakEngine that
+ * handles characters that no other LanguageBreakEngine is available to
+ * handle. It is told the character and the type of break; at its
+ * discretion it may handle more than the specified character (e.g.,
+ * the entire script to which that character belongs.</p>
+ *
+ * <p>UnhandledEngines may not be shared between threads without
+ * external synchronization.</p>
+ */
+
+class UnhandledEngine : public LanguageBreakEngine {
+ private:
+
+    /**
+     * The sets of characters handled, for each break type
+     * @internal
+     */
+
+  UnicodeSet    *fHandled[4];
+
+ public:
+
+  /**
+   * <p>Default constructor.</p>
+   *
+   */
+  UnhandledEngine(UErrorCode &status);
+
+  /**
+   * <p>Virtual destructor.</p>
+   */
+  virtual ~UnhandledEngine();
+
+ /**
+  * <p>Indicate whether this engine handles a particular character for
+  * a particular kind of break.</p>
+  *
+  * @param c A character which begins a run that the engine might handle
+  * @param breakType The type of text break which the caller wants to determine
+  * @return TRUE if this engine handles the particular character and break
+  * type.
+  */
+  virtual UBool handles(UChar32 c, int32_t breakType) const;
+
+ /**
+  * <p>Find any breaks within a run in the supplied text.</p>
+  *
+  * @param text A UText representing the text (TODO: UText). The
+  * iterator is left at the end of the run of characters which the engine
+  * is capable of handling.
+  * @param startPos The start of the run within the supplied text.
+  * @param endPos The end of the run within the supplied text.
+  * @param reverse Whether the caller is looking for breaks in a reverse
+  * direction.
+  * @param breakType The type of break desired, or -1.
+  * @param foundBreaks An allocated C array of the breaks found, if any
+  * @return The number of breaks found.
+  */
+  virtual int32_t findBreaks( UText *text,
+                              int32_t startPos,
+                              int32_t endPos,
+                              UBool reverse,
+                              int32_t breakType,
+                              UStack &foundBreaks ) const;
+
+ /**
+  * <p>Tell the engine to handle a particular character and break type.</p>
+  *
+  * @param c A character which the engine should handle
+  * @param breakType The type of text break for which the engine should handle c
+  */
+  virtual void handleCharacter(UChar32 c, int32_t breakType);
+
+};
+
+/*******************************************************************
+ * ICULanguageBreakFactory
+ */
+
+/**
+ * <p>ICULanguageBreakFactory is the default LanguageBreakFactory for
+ * ICU. It creates dictionary-based LanguageBreakEngines from dictionary
+ * data in the ICU data file.</p>
+ */
+class ICULanguageBreakFactory : public LanguageBreakFactory {
+ private:
+
+    /**
+     * The stack of break engines created by this factory
+     * @internal
+     */
+
+  UStack    *fEngines;
+
+ public:
+
+  /**
+   * <p>Standard constructor.</p>
+   *
+   */
+  ICULanguageBreakFactory(UErrorCode &status);
+
+  /**
+   * <p>Virtual destructor.</p>
+   */
+  virtual ~ICULanguageBreakFactory();
+
+ /**
+  * <p>Find and return a LanguageBreakEngine that can find the desired
+  * kind of break for the set of characters to which the supplied
+  * character belongs. It is up to the set of available engines to
+  * determine what the sets of characters are.</p>
+  *
+  * @param c A character that begins a run for which a LanguageBreakEngine is
+  * sought.
+  * @param breakType The kind of text break for which a LanguageBreakEngine is
+  * sought.
+  * @return A LanguageBreakEngine with the desired characteristics, or 0.
+  */
+  virtual const LanguageBreakEngine *getEngineFor(UChar32 c, int32_t breakType);
+
+ protected:
+
+ /**
+  * <p>Create a LanguageBreakEngine for the set of characters to which
+  * the supplied character belongs, for the specified break type.</p>
+  *
+  * @param c A character that begins a run for which a LanguageBreakEngine is
+  * sought.
+  * @param breakType The kind of text break for which a LanguageBreakEngine is
+  * sought.
+  * @return A LanguageBreakEngine with the desired characteristics, or 0.
+  */
+  virtual const LanguageBreakEngine *loadEngineFor(UChar32 c, int32_t breakType);
+
+ /**
+  * <p>Create a CompactTrieDictionary for the specified script and break type.</p>
+  *
+  * @param script An ISO 15924 script code that identifies the dictionary to be
+  * created.
+  * @param breakType The kind of text break for which a dictionary is
+  * sought.
+  * @return A CompactTrieDictionary with the desired characteristics, or 0.
+  */
+  virtual const CompactTrieDictionary *loadDictionaryFor(UScriptCode script, int32_t breakType);
+
+};
+
+U_NAMESPACE_END
+
+    /* BRKENG_H */
+#endif
diff --git a/icu/source/common/brkiter.cpp b/icu/source/common/brkiter.cpp
new file mode 100644
index 0000000..26f7b6a
--- /dev/null
+++ b/icu/source/common/brkiter.cpp
@@ -0,0 +1,443 @@
+/*
+*******************************************************************************
+* Copyright (C) 1997-2010, International Business Machines Corporation and
+* others. All Rights Reserved.
+*******************************************************************************
+*
+* File TXTBDRY.CPP
+*
+* Modification History:
+*
+*   Date        Name        Description
+*   02/18/97    aliu        Converted from OpenClass.  Added DONE.
+*   01/13/2000  helena      Added UErrorCode parameter to createXXXInstance methods.
+*****************************************************************************************
+*/
+
+// *****************************************************************************
+// This file was generated from the java source file BreakIterator.java
+// *****************************************************************************
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/rbbi.h"
+#include "unicode/brkiter.h"
+#include "unicode/udata.h"
+#include "unicode/ures.h"
+#include "unicode/ustring.h"
+#include "ucln_cmn.h"
+#include "cstring.h"
+#include "umutex.h"
+#include "servloc.h"
+#include "locbased.h"
+#include "uresimp.h"
+#include "uassert.h"
+#include "ubrkimpl.h"
+
+// *****************************************************************************
+// class BreakIterator
+// This class implements methods for finding the location of boundaries in text.
+// Instances of BreakIterator maintain a current position and scan over text
+// returning the index of characters where boundaries occur.
+// *****************************************************************************
+
+U_NAMESPACE_BEGIN
+
+// -------------------------------------
+
+BreakIterator*
+BreakIterator::buildInstance(const Locale& loc, const char *type, int32_t kind, UErrorCode &status)
+{
+    char fnbuff[256];
+    char ext[4]={'\0'};
+    char actualLocale[ULOC_FULLNAME_CAPACITY];
+    int32_t size;
+    const UChar* brkfname = NULL;
+    UResourceBundle brkRulesStack;
+    UResourceBundle brkNameStack;
+    UResourceBundle *brkRules = &brkRulesStack;
+    UResourceBundle *brkName  = &brkNameStack;
+    RuleBasedBreakIterator *result = NULL;
+
+    if (U_FAILURE(status))
+        return NULL;
+
+    ures_initStackObject(brkRules);
+    ures_initStackObject(brkName);
+
+    // Get the locale
+    UResourceBundle *b = ures_open(U_ICUDATA_BRKITR, loc.getName(), &status);
+    /* this is a hack for now. Should be fixed when the data is fetched from
+        brk_index.txt */
+    if(status==U_USING_DEFAULT_WARNING){
+        status=U_ZERO_ERROR;
+        ures_openFillIn(b, U_ICUDATA_BRKITR, "", &status);
+    }
+
+    // Get the "boundaries" array.
+    if (U_SUCCESS(status)) {
+        brkRules = ures_getByKeyWithFallback(b, "boundaries", brkRules, &status);
+        // Get the string object naming the rules file
+        brkName = ures_getByKeyWithFallback(brkRules, type, brkName, &status);
+        // Get the actual string
+        brkfname = ures_getString(brkName, &size, &status);
+        U_ASSERT((size_t)size<sizeof(fnbuff));
+        if ((size_t)size>=sizeof(fnbuff)) {
+            size=0;
+            if (U_SUCCESS(status)) {
+                status = U_BUFFER_OVERFLOW_ERROR;
+            }
+        }
+
+        // Use the string if we found it
+        if (U_SUCCESS(status) && brkfname) {
+            uprv_strncpy(actualLocale,
+                ures_getLocale(brkName, &status),
+                sizeof(actualLocale)/sizeof(actualLocale[0]));
+
+            UChar* extStart=u_strchr(brkfname, 0x002e);
+            int len = 0;
+            if(extStart!=NULL){
+                len = (int)(extStart-brkfname);
+                u_UCharsToChars(extStart+1, ext, sizeof(ext)); // nul terminates the buff
+                u_UCharsToChars(brkfname, fnbuff, len);
+            }
+            fnbuff[len]=0; // nul terminate
+        }
+    }
+
+    ures_close(brkRules);
+    ures_close(brkName);
+
+    UDataMemory* file = udata_open(U_ICUDATA_BRKITR, ext, fnbuff, &status);
+    if (U_FAILURE(status)) {
+        ures_close(b);
+        return NULL;
+    }
+
+    // Create a RuleBasedBreakIterator
+    result = new RuleBasedBreakIterator(file, status);
+
+    // If there is a result, set the valid locale and actual locale, and the kind
+    if (U_SUCCESS(status) && result != NULL) {
+        U_LOCALE_BASED(locBased, *(BreakIterator*)result);
+        locBased.setLocaleIDs(ures_getLocaleByType(b, ULOC_VALID_LOCALE, &status), actualLocale);
+        result->setBreakType(kind);
+    }
+
+    ures_close(b);
+
+    if (U_FAILURE(status) && result != NULL) {  // Sometimes redundant check, but simple
+        delete result;
+        return NULL;
+    }
+
+    if (result == NULL) {
+        udata_close(file);
+        if (U_SUCCESS(status)) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+        }
+    }
+
+    return result;
+}
+
+// Creates a break iterator for word breaks.
+BreakIterator* U_EXPORT2
+BreakIterator::createWordInstance(const Locale& key, UErrorCode& status)
+{
+    return createInstance(key, UBRK_WORD, status);
+}
+
+// -------------------------------------
+
+// Creates a break iterator  for line breaks.
+BreakIterator* U_EXPORT2
+BreakIterator::createLineInstance(const Locale& key, UErrorCode& status)
+{
+    return createInstance(key, UBRK_LINE, status);
+}
+
+// -------------------------------------
+
+// Creates a break iterator  for character breaks.
+BreakIterator* U_EXPORT2
+BreakIterator::createCharacterInstance(const Locale& key, UErrorCode& status)
+{
+    return createInstance(key, UBRK_CHARACTER, status);
+}
+
+// -------------------------------------
+
+// Creates a break iterator  for sentence breaks.
+BreakIterator* U_EXPORT2
+BreakIterator::createSentenceInstance(const Locale& key, UErrorCode& status)
+{
+    return createInstance(key, UBRK_SENTENCE, status);
+}
+
+// -------------------------------------
+
+// Creates a break iterator for title casing breaks.
+BreakIterator* U_EXPORT2
+BreakIterator::createTitleInstance(const Locale& key, UErrorCode& status)
+{
+    return createInstance(key, UBRK_TITLE, status);
+}
+
+// -------------------------------------
+
+// Gets all the available locales that has localized text boundary data.
+const Locale* U_EXPORT2
+BreakIterator::getAvailableLocales(int32_t& count)
+{
+    return Locale::getAvailableLocales(count);
+}
+
+// ------------------------------------------
+//
+// Default constructor and destructor
+//
+//-------------------------------------------
+
+BreakIterator::BreakIterator()
+{
+    fBufferClone = FALSE;
+    *validLocale = *actualLocale = 0;
+}
+
+BreakIterator::~BreakIterator()
+{
+}
+
+// ------------------------------------------
+//
+// Registration
+//
+//-------------------------------------------
+#if !UCONFIG_NO_SERVICE
+
+// -------------------------------------
+
+class ICUBreakIteratorFactory : public ICUResourceBundleFactory {
+protected:
+    virtual UObject* handleCreate(const Locale& loc, int32_t kind, const ICUService* /*service*/, UErrorCode& status) const {
+        return BreakIterator::makeInstance(loc, kind, status);
+    }
+};
+
+// -------------------------------------
+
+class ICUBreakIteratorService : public ICULocaleService {
+public:
+    ICUBreakIteratorService()
+        : ICULocaleService(UNICODE_STRING("Break Iterator", 14))
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        registerFactory(new ICUBreakIteratorFactory(), status);
+    }
+
+    virtual UObject* cloneInstance(UObject* instance) const {
+        return ((BreakIterator*)instance)->clone();
+    }
+
+    virtual UObject* handleDefault(const ICUServiceKey& key, UnicodeString* /*actualID*/, UErrorCode& status) const {
+        LocaleKey& lkey = (LocaleKey&)key;
+        int32_t kind = lkey.kind();
+        Locale loc;
+        lkey.currentLocale(loc);
+        return BreakIterator::makeInstance(loc, kind, status);
+    }
+
+    virtual UBool isDefault() const {
+        return countFactories() == 1;
+    }
+};
+
+// -------------------------------------
+
+U_NAMESPACE_END
+
+// defined in ucln_cmn.h
+
+static U_NAMESPACE_QUALIFIER ICULocaleService* gService = NULL;
+
+/**
+ * Release all static memory held by breakiterator.
+ */
+U_CDECL_BEGIN
+static UBool U_CALLCONV breakiterator_cleanup(void) {
+#if !UCONFIG_NO_SERVICE
+    if (gService) {
+        delete gService;
+        gService = NULL;
+    }
+#endif
+    return TRUE;
+}
+U_CDECL_END
+U_NAMESPACE_BEGIN
+
+static ICULocaleService*
+getService(void)
+{
+    UBool needsInit;
+    UMTX_CHECK(NULL, (UBool)(gService == NULL), needsInit);
+
+    if (needsInit) {
+        ICULocaleService  *tService = new ICUBreakIteratorService();
+        umtx_lock(NULL);
+        if (gService == NULL) {
+            gService = tService;
+            tService = NULL;
+            ucln_common_registerCleanup(UCLN_COMMON_BREAKITERATOR, breakiterator_cleanup);
+        }
+        umtx_unlock(NULL);
+        delete tService;
+    }
+    return gService;
+}
+
+// -------------------------------------
+
+static inline UBool
+hasService(void)
+{
+    UBool retVal;
+    UMTX_CHECK(NULL, gService != NULL, retVal);
+    return retVal;
+}
+
+// -------------------------------------
+
+URegistryKey U_EXPORT2
+BreakIterator::registerInstance(BreakIterator* toAdopt, const Locale& locale, UBreakIteratorType kind, UErrorCode& status)
+{
+    ICULocaleService *service = getService();
+    if (service == NULL) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
+    }
+    return service->registerInstance(toAdopt, locale, kind, status);
+}
+
+// -------------------------------------
+
+UBool U_EXPORT2
+BreakIterator::unregister(URegistryKey key, UErrorCode& status)
+{
+    if (U_SUCCESS(status)) {
+        if (hasService()) {
+            return gService->unregister(key, status);
+        }
+        status = U_MEMORY_ALLOCATION_ERROR;
+    }
+    return FALSE;
+}
+
+// -------------------------------------
+
+StringEnumeration* U_EXPORT2
+BreakIterator::getAvailableLocales(void)
+{
+    ICULocaleService *service = getService();
+    if (service == NULL) {
+        return NULL;
+    }
+    return service->getAvailableLocales();
+}
+#endif /* UCONFIG_NO_SERVICE */
+
+// -------------------------------------
+
+BreakIterator*
+BreakIterator::createInstance(const Locale& loc, int32_t kind, UErrorCode& status)
+{
+    if (U_FAILURE(status)) {
+        return NULL;
+    }
+
+#if !UCONFIG_NO_SERVICE
+    if (hasService()) {
+        Locale actualLoc("");
+        BreakIterator *result = (BreakIterator*)gService->get(loc, kind, &actualLoc, status);
+        // TODO: The way the service code works in ICU 2.8 is that if
+        // there is a real registered break iterator, the actualLoc
+        // will be populated, but if the handleDefault path is taken
+        // (because nothing is registered that can handle the
+        // requested locale) then the actualLoc comes back empty.  In
+        // that case, the returned object already has its actual/valid
+        // locale data populated (by makeInstance, which is what
+        // handleDefault calls), so we don't touch it.  YES, A COMMENT
+        // THIS LONG is a sign of bad code -- so the action item is to
+        // revisit this in ICU 3.0 and clean it up/fix it/remove it.
+        if (U_SUCCESS(status) && (result != NULL) && *actualLoc.getName() != 0) {
+            U_LOCALE_BASED(locBased, *result);
+            locBased.setLocaleIDs(actualLoc.getName(), actualLoc.getName());
+        }
+        return result;
+    }
+    else
+#endif
+    {
+        return makeInstance(loc, kind, status);
+    }
+}
+
+// -------------------------------------
+
+BreakIterator*
+BreakIterator::makeInstance(const Locale& loc, int32_t kind, UErrorCode& status)
+{
+
+    if (U_FAILURE(status)) {
+        return NULL;
+    }
+
+    BreakIterator *result = NULL;
+    switch (kind) {
+    case UBRK_CHARACTER:
+        result = BreakIterator::buildInstance(loc, "grapheme", kind, status);
+        break;
+    case UBRK_WORD:
+        result = BreakIterator::buildInstance(loc, "word", kind, status);
+        break;
+    case UBRK_LINE:
+        result = BreakIterator::buildInstance(loc, "line", kind, status);
+        break;
+    case UBRK_SENTENCE:
+        result = BreakIterator::buildInstance(loc, "sentence", kind, status);
+        break;
+    case UBRK_TITLE:
+        result = BreakIterator::buildInstance(loc, "title", kind, status);
+        break;
+    default:
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+    }
+
+    if (U_FAILURE(status)) {
+        return NULL;
+    }
+
+    return result;
+}
+
+Locale
+BreakIterator::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
+    U_LOCALE_BASED(locBased, *this);
+    return locBased.getLocale(type, status);
+}
+
+const char *
+BreakIterator::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const {
+    U_LOCALE_BASED(locBased, *this);
+    return locBased.getLocaleID(type, status);
+}
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
+
+//eof
diff --git a/icu/source/common/bytestream.cpp b/icu/source/common/bytestream.cpp
new file mode 100644
index 0000000..09ca50c
--- /dev/null
+++ b/icu/source/common/bytestream.cpp
@@ -0,0 +1,65 @@
+// Copyright (C) 2009, International Business Machines
+// Corporation and others. All Rights Reserved.
+//
+// Copyright 2007 Google Inc. All Rights Reserved.
+// Author: sanjay@google.com (Sanjay Ghemawat)
+
+#include "unicode/utypes.h"
+#include "unicode/bytestream.h"
+#include "cmemory.h"
+
+U_NAMESPACE_BEGIN
+
+char* ByteSink::GetAppendBuffer(int32_t min_capacity,
+                                int32_t /*desired_capacity_hint*/,
+                                char* scratch, int32_t scratch_capacity,
+                                int32_t* result_capacity) {
+  if (min_capacity < 1 || scratch_capacity < min_capacity) {
+    *result_capacity = 0;
+    return NULL;
+  }
+  *result_capacity = scratch_capacity;
+  return scratch;
+}
+
+void ByteSink::Flush() {}
+
+CheckedArrayByteSink::CheckedArrayByteSink(char* outbuf, int32_t capacity)
+    : outbuf_(outbuf), capacity_(capacity < 0 ? 0 : capacity), size_(0), overflowed_(false) {
+}
+
+void CheckedArrayByteSink::Append(const char* bytes, int32_t n) {
+  if (n <= 0) {
+    return;
+  }
+  int32_t available = capacity_ - size_;
+  if (n > available) {
+    n = available;
+    overflowed_ = true;
+  }
+  if (n > 0 && bytes != (outbuf_ + size_)) {
+    uprv_memcpy(outbuf_ + size_, bytes, n);
+  }
+  size_ += n;
+}
+
+char* CheckedArrayByteSink::GetAppendBuffer(int32_t min_capacity,
+                                            int32_t /*desired_capacity_hint*/,
+                                            char* scratch,
+                                            int32_t scratch_capacity,
+                                            int32_t* result_capacity) {
+  if (min_capacity < 1 || scratch_capacity < min_capacity) {
+    *result_capacity = 0;
+    return NULL;
+  }
+  int32_t available = capacity_ - size_;
+  if (available >= min_capacity) {
+    *result_capacity = available;
+    return outbuf_ + size_;
+  } else {
+    *result_capacity = scratch_capacity;
+    return scratch;
+  }
+}
+
+U_NAMESPACE_END
diff --git a/icu/source/common/caniter.cpp b/icu/source/common/caniter.cpp
new file mode 100644
index 0000000..c11c31e
--- /dev/null
+++ b/icu/source/common/caniter.cpp
@@ -0,0 +1,574 @@
+/*
+ *****************************************************************************
+ * Copyright (C) 1996-2010, International Business Machines Corporation and  *
+ * others. All Rights Reserved.                                              *
+ *****************************************************************************
+ */
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_NORMALIZATION
+
+#include "unicode/uset.h"
+#include "unicode/ustring.h"
+#include "hash.h"
+#include "normalizer2impl.h"
+#include "unormimp.h"
+#include "unicode/caniter.h"
+#include "unicode/normlzr.h"
+#include "unicode/uchar.h"
+#include "cmemory.h"
+
+/**
+ * This class allows one to iterate through all the strings that are canonically equivalent to a given
+ * string. For example, here are some sample results:
+Results for: {LATIN CAPITAL LETTER A WITH RING ABOVE}{LATIN SMALL LETTER D}{COMBINING DOT ABOVE}{COMBINING CEDILLA}
+1: \u0041\u030A\u0064\u0307\u0327
+ = {LATIN CAPITAL LETTER A}{COMBINING RING ABOVE}{LATIN SMALL LETTER D}{COMBINING DOT ABOVE}{COMBINING CEDILLA}
+2: \u0041\u030A\u0064\u0327\u0307
+ = {LATIN CAPITAL LETTER A}{COMBINING RING ABOVE}{LATIN SMALL LETTER D}{COMBINING CEDILLA}{COMBINING DOT ABOVE}
+3: \u0041\u030A\u1E0B\u0327
+ = {LATIN CAPITAL LETTER A}{COMBINING RING ABOVE}{LATIN SMALL LETTER D WITH DOT ABOVE}{COMBINING CEDILLA}
+4: \u0041\u030A\u1E11\u0307
+ = {LATIN CAPITAL LETTER A}{COMBINING RING ABOVE}{LATIN SMALL LETTER D WITH CEDILLA}{COMBINING DOT ABOVE}
+5: \u00C5\u0064\u0307\u0327
+ = {LATIN CAPITAL LETTER A WITH RING ABOVE}{LATIN SMALL LETTER D}{COMBINING DOT ABOVE}{COMBINING CEDILLA}
+6: \u00C5\u0064\u0327\u0307
+ = {LATIN CAPITAL LETTER A WITH RING ABOVE}{LATIN SMALL LETTER D}{COMBINING CEDILLA}{COMBINING DOT ABOVE}
+7: \u00C5\u1E0B\u0327
+ = {LATIN CAPITAL LETTER A WITH RING ABOVE}{LATIN SMALL LETTER D WITH DOT ABOVE}{COMBINING CEDILLA}
+8: \u00C5\u1E11\u0307
+ = {LATIN CAPITAL LETTER A WITH RING ABOVE}{LATIN SMALL LETTER D WITH CEDILLA}{COMBINING DOT ABOVE}
+9: \u212B\u0064\u0307\u0327
+ = {ANGSTROM SIGN}{LATIN SMALL LETTER D}{COMBINING DOT ABOVE}{COMBINING CEDILLA}
+10: \u212B\u0064\u0327\u0307
+ = {ANGSTROM SIGN}{LATIN SMALL LETTER D}{COMBINING CEDILLA}{COMBINING DOT ABOVE}
+11: \u212B\u1E0B\u0327
+ = {ANGSTROM SIGN}{LATIN SMALL LETTER D WITH DOT ABOVE}{COMBINING CEDILLA}
+12: \u212B\u1E11\u0307
+ = {ANGSTROM SIGN}{LATIN SMALL LETTER D WITH CEDILLA}{COMBINING DOT ABOVE}
+ *<br>Note: the code is intended for use with small strings, and is not suitable for larger ones,
+ * since it has not been optimized for that situation.
+ *@author M. Davis
+ *@draft
+ */
+
+// public
+
+U_NAMESPACE_BEGIN
+
+// TODO: add boilerplate methods.
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CanonicalIterator)
+
+/**
+ *@param source string to get results for
+ */
+CanonicalIterator::CanonicalIterator(const UnicodeString &sourceStr, UErrorCode &status) :
+    pieces(NULL),
+    pieces_length(0),
+    pieces_lengths(NULL),
+    current(NULL),
+    current_length(0),
+    nfd(*Normalizer2Factory::getNFDInstance(status))
+{
+    if(U_SUCCESS(status)) {
+      setSource(sourceStr, status);
+    }
+}
+
+CanonicalIterator::~CanonicalIterator() {
+  cleanPieces();
+}
+
+void CanonicalIterator::cleanPieces() {
+    int32_t i = 0;
+    if(pieces != NULL) {
+        for(i = 0; i < pieces_length; i++) {
+            if(pieces[i] != NULL) {
+                delete[] pieces[i];
+            }
+        }
+        uprv_free(pieces);
+        pieces = NULL;
+        pieces_length = 0;
+    }
+    if(pieces_lengths != NULL) {
+        uprv_free(pieces_lengths);
+        pieces_lengths = NULL;
+    }
+    if(current != NULL) {
+        uprv_free(current);
+        current = NULL;
+        current_length = 0;
+    }
+}
+
+/**
+ *@return gets the source: NOTE: it is the NFD form of source
+ */
+UnicodeString CanonicalIterator::getSource() {
+  return source;
+}
+
+/**
+ * Resets the iterator so that one can start again from the beginning.
+ */
+void CanonicalIterator::reset() {
+    done = FALSE;
+    for (int i = 0; i < current_length; ++i) {
+        current[i] = 0;
+    }
+}
+
+/**
+ *@return the next string that is canonically equivalent. The value null is returned when
+ * the iteration is done.
+ */
+UnicodeString CanonicalIterator::next() {
+    int32_t i = 0;
+
+    if (done) {
+      buffer.setToBogus();
+      return buffer;
+    }
+
+    // delete old contents
+    buffer.remove();
+
+    // construct return value
+
+    for (i = 0; i < pieces_length; ++i) {
+        buffer.append(pieces[i][current[i]]);
+    }
+    //String result = buffer.toString(); // not needed
+
+    // find next value for next time
+
+    for (i = current_length - 1; ; --i) {
+        if (i < 0) {
+            done = TRUE;
+            break;
+        }
+        current[i]++;
+        if (current[i] < pieces_lengths[i]) break; // got sequence
+        current[i] = 0;
+    }
+    return buffer;
+}
+
+/**
+ *@param set the source string to iterate against. This allows the same iterator to be used
+ * while changing the source string, saving object creation.
+ */
+void CanonicalIterator::setSource(const UnicodeString &newSource, UErrorCode &status) {
+    int32_t list_length = 0;
+    UChar32 cp = 0;
+    int32_t start = 0;
+    int32_t i = 0;
+    UnicodeString *list = NULL;
+
+    Normalizer::normalize(newSource, UNORM_NFD, 0, source, status);
+    if(U_FAILURE(status)) {
+      return;
+    }
+    done = FALSE;
+
+    cleanPieces();
+
+    // catch degenerate case
+    if (newSource.length() == 0) {
+        pieces = (UnicodeString **)uprv_malloc(sizeof(UnicodeString *));
+        pieces_lengths = (int32_t*)uprv_malloc(1 * sizeof(int32_t));
+        pieces_length = 1;
+        current = (int32_t*)uprv_malloc(1 * sizeof(int32_t));
+        current_length = 1;
+        if (pieces == NULL || pieces_lengths == NULL || current == NULL) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            goto CleanPartialInitialization;
+        }
+        current[0] = 0;
+        pieces[0] = new UnicodeString[1];
+        pieces_lengths[0] = 1;
+        if (pieces[0] == 0) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            goto CleanPartialInitialization;
+        }
+        return;
+    }
+
+
+    list = new UnicodeString[source.length()];
+    if (list == 0) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        goto CleanPartialInitialization;
+    }
+
+    // i should initialy be the number of code units at the 
+    // start of the string
+    i = UTF16_CHAR_LENGTH(source.char32At(0));
+    //int32_t i = 1;
+    // find the segments
+    // This code iterates through the source string and 
+    // extracts segments that end up on a codepoint that
+    // doesn't start any decompositions. (Analysis is done
+    // on the NFD form - see above).
+    for (; i < source.length(); i += UTF16_CHAR_LENGTH(cp)) {
+        cp = source.char32At(i);
+        if (unorm_isCanonSafeStart(cp)) {
+            source.extract(start, i-start, list[list_length++]); // add up to i
+            start = i;
+        }
+    }
+    source.extract(start, i-start, list[list_length++]); // add last one
+
+
+    // allocate the arrays, and find the strings that are CE to each segment
+    pieces = (UnicodeString **)uprv_malloc(list_length * sizeof(UnicodeString *));
+    pieces_length = list_length;
+    pieces_lengths = (int32_t*)uprv_malloc(list_length * sizeof(int32_t));
+    current = (int32_t*)uprv_malloc(list_length * sizeof(int32_t));
+    current_length = list_length;
+    if (pieces == NULL || pieces_lengths == NULL || current == NULL) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        goto CleanPartialInitialization;
+    }
+
+    for (i = 0; i < current_length; i++) {
+        current[i] = 0;
+    }
+    // for each segment, get all the combinations that can produce 
+    // it after NFD normalization
+    for (i = 0; i < pieces_length; ++i) {
+        //if (PROGRESS) printf("SEGMENT\n");
+        pieces[i] = getEquivalents(list[i], pieces_lengths[i], status);
+    }
+
+    delete[] list;
+    return;
+// Common section to cleanup all local variables and reset object variables.
+CleanPartialInitialization:
+    if (list != NULL) {
+        delete[] list;
+    }
+    cleanPieces();
+}
+
+/**
+ * Dumb recursive implementation of permutation.
+ * TODO: optimize
+ * @param source the string to find permutations for
+ * @return the results in a set.
+ */
+void U_EXPORT2 CanonicalIterator::permute(UnicodeString &source, UBool skipZeros, Hashtable *result, UErrorCode &status) {
+    if(U_FAILURE(status)) {
+        return;
+    }
+    //if (PROGRESS) printf("Permute: %s\n", UToS(Tr(source)));
+    int32_t i = 0;
+
+    // optimization:
+    // if zero or one character, just return a set with it
+    // we check for length < 2 to keep from counting code points all the time
+    if (source.length() <= 2 && source.countChar32() <= 1) {
+        UnicodeString *toPut = new UnicodeString(source);
+        /* test for NULL */
+        if (toPut == 0) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+        result->put(source, toPut, status);
+        return;
+    }
+
+    // otherwise iterate through the string, and recursively permute all the other characters
+    UChar32 cp;
+    Hashtable subpermute(status);
+    if(U_FAILURE(status)) {
+        return;
+    }
+    subpermute.setValueDeleter(uhash_deleteUnicodeString);
+
+    for (i = 0; i < source.length(); i += UTF16_CHAR_LENGTH(cp)) {
+        cp = source.char32At(i);
+        const UHashElement *ne = NULL;
+        int32_t el = -1;
+        UnicodeString subPermuteString = source;
+
+        // optimization:
+        // if the character is canonical combining class zero,
+        // don't permute it
+        if (skipZeros && i != 0 && u_getCombiningClass(cp) == 0) {
+            //System.out.println("Skipping " + Utility.hex(UTF16.valueOf(source, i)));
+            continue;
+        }
+
+        subpermute.removeAll();
+
+        // see what the permutations of the characters before and after this one are
+        //Hashtable *subpermute = permute(source.substring(0,i) + source.substring(i + UTF16.getCharCount(cp)));
+        permute(subPermuteString.replace(i, UTF16_CHAR_LENGTH(cp), NULL, 0), skipZeros, &subpermute, status);
+        /* Test for buffer overflows */
+        if(U_FAILURE(status)) {
+            return;
+        }
+        // The upper replace is destructive. The question is do we have to make a copy, or we don't care about the contents 
+        // of source at this point.
+
+        // prefix this character to all of them
+        ne = subpermute.nextElement(el);
+        while (ne != NULL) {
+            UnicodeString *permRes = (UnicodeString *)(ne->value.pointer);
+            UnicodeString *chStr = new UnicodeString(cp);
+            //test for  NULL
+            if (chStr == NULL) {
+                status = U_MEMORY_ALLOCATION_ERROR;
+                return;
+            }
+            chStr->append(*permRes); //*((UnicodeString *)(ne->value.pointer));
+            //if (PROGRESS) printf("  Piece: %s\n", UToS(*chStr));
+            result->put(*chStr, chStr, status);
+            ne = subpermute.nextElement(el);
+        }
+    }
+    //return result;
+}
+
+// privates
+
+// we have a segment, in NFD. Find all the strings that are canonically equivalent to it.
+UnicodeString* CanonicalIterator::getEquivalents(const UnicodeString &segment, int32_t &result_len, UErrorCode &status) {
+    Hashtable result(status);
+    Hashtable permutations(status);
+    Hashtable basic(status);
+    if (U_FAILURE(status)) {
+        return 0;
+    }
+    result.setValueDeleter(uhash_deleteUnicodeString);
+    permutations.setValueDeleter(uhash_deleteUnicodeString);
+    basic.setValueDeleter(uhash_deleteUnicodeString);
+
+    UChar USeg[256];
+    int32_t segLen = segment.extract(USeg, 256, status);
+    getEquivalents2(&basic, USeg, segLen, status);
+
+    // now get all the permutations
+    // add only the ones that are canonically equivalent
+    // TODO: optimize by not permuting any class zero.
+
+    const UHashElement *ne = NULL;
+    int32_t el = -1;
+    //Iterator it = basic.iterator();
+    ne = basic.nextElement(el);
+    //while (it.hasNext())
+    while (ne != NULL) {
+        //String item = (String) it.next();
+        UnicodeString item = *((UnicodeString *)(ne->value.pointer));
+
+        permutations.removeAll();
+        permute(item, CANITER_SKIP_ZEROES, &permutations, status);
+        const UHashElement *ne2 = NULL;
+        int32_t el2 = -1;
+        //Iterator it2 = permutations.iterator();
+        ne2 = permutations.nextElement(el2);
+        //while (it2.hasNext())
+        while (ne2 != NULL) {
+            //String possible = (String) it2.next();
+            //UnicodeString *possible = new UnicodeString(*((UnicodeString *)(ne2->value.pointer)));
+            UnicodeString possible(*((UnicodeString *)(ne2->value.pointer)));
+            UnicodeString attempt;
+            Normalizer::normalize(possible, UNORM_NFD, 0, attempt, status);
+
+            // TODO: check if operator == is semanticaly the same as attempt.equals(segment)
+            if (attempt==segment) {
+                //if (PROGRESS) printf("Adding Permutation: %s\n", UToS(Tr(*possible)));
+                // TODO: use the hashtable just to catch duplicates - store strings directly (somehow).
+                result.put(possible, new UnicodeString(possible), status); //add(possible);
+            } else {
+                //if (PROGRESS) printf("-Skipping Permutation: %s\n", UToS(Tr(*possible)));
+            }
+
+            ne2 = permutations.nextElement(el2);
+        }
+        ne = basic.nextElement(el);
+    }
+
+    /* Test for buffer overflows */
+    if(U_FAILURE(status)) {
+        return 0;
+    }
+    // convert into a String[] to clean up storage
+    //String[] finalResult = new String[result.size()];
+    UnicodeString *finalResult = NULL;
+    int32_t resultCount;
+    if((resultCount = result.count())) {
+        finalResult = new UnicodeString[resultCount];
+        if (finalResult == 0) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            return NULL;
+        }
+    }
+    else {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return NULL;
+    }
+    //result.toArray(finalResult);
+    result_len = 0;
+    el = -1;
+    ne = result.nextElement(el);
+    while(ne != NULL) {
+        finalResult[result_len++] = *((UnicodeString *)(ne->value.pointer));
+        ne = result.nextElement(el);
+    }
+
+
+    return finalResult;
+}
+
+Hashtable *CanonicalIterator::getEquivalents2(Hashtable *fillinResult, const UChar *segment, int32_t segLen, UErrorCode &status) {
+
+    if (U_FAILURE(status)) {
+        return NULL;
+    }
+
+    //if (PROGRESS) printf("Adding: %s\n", UToS(Tr(segment)));
+
+    UnicodeString toPut(segment, segLen);
+
+    fillinResult->put(toPut, new UnicodeString(toPut), status);
+
+    USerializedSet starts;
+
+    // cycle through all the characters
+    UChar32 cp, end = 0;
+    int32_t i = 0, j;
+    for (i = 0; i < segLen; i += UTF16_CHAR_LENGTH(cp)) {
+        // see if any character is at the start of some decomposition
+        UTF_GET_CHAR(segment, 0, i, segLen, cp);
+        if (!unorm_getCanonStartSet(cp, &starts)) {
+            continue;
+        }
+        // if so, see which decompositions match 
+        for(j = 0, cp = end+1; cp <= end || uset_getSerializedRange(&starts, j++, &cp, &end); ++cp) {
+            Hashtable remainder(status);
+            remainder.setValueDeleter(uhash_deleteUnicodeString);
+            if (extract(&remainder, cp, segment, segLen, i, status) == NULL) {
+                continue;
+            }
+
+            // there were some matches, so add all the possibilities to the set.
+            UnicodeString prefix(segment, i);
+            prefix += cp;
+
+            int32_t el = -1;
+            const UHashElement *ne = remainder.nextElement(el);
+            while (ne != NULL) {
+                UnicodeString item = *((UnicodeString *)(ne->value.pointer));
+                UnicodeString *toAdd = new UnicodeString(prefix);
+                /* test for NULL */
+                if (toAdd == 0) {
+                    status = U_MEMORY_ALLOCATION_ERROR;
+                    return NULL;
+                }
+                *toAdd += item;
+                fillinResult->put(*toAdd, toAdd, status);
+
+                //if (PROGRESS) printf("Adding: %s\n", UToS(Tr(*toAdd)));
+
+                ne = remainder.nextElement(el);
+            }
+        }
+    }
+
+    /* Test for buffer overflows */
+    if(U_FAILURE(status)) {
+        return NULL;
+    }
+    return fillinResult;
+}
+
+/**
+ * See if the decomposition of cp2 is at segment starting at segmentPos 
+ * (with canonical rearrangment!)
+ * If so, take the remainder, and return the equivalents 
+ */
+Hashtable *CanonicalIterator::extract(Hashtable *fillinResult, UChar32 comp, const UChar *segment, int32_t segLen, int32_t segmentPos, UErrorCode &status) {
+//Hashtable *CanonicalIterator::extract(UChar32 comp, const UnicodeString &segment, int32_t segLen, int32_t segmentPos, UErrorCode &status) {
+    //if (PROGRESS) printf(" extract: %s, ", UToS(Tr(UnicodeString(comp))));
+    //if (PROGRESS) printf("%s, %i\n", UToS(Tr(segment)), segmentPos);
+
+    if (U_FAILURE(status)) {
+        return NULL;
+    }
+
+    UnicodeString temp(comp);
+    int32_t inputLen=temp.length();
+    UnicodeString decompString;
+    nfd.normalize(temp, decompString, status);
+    const UChar *decomp=decompString.getBuffer();
+    int32_t decompLen=decompString.length();
+
+    // See if it matches the start of segment (at segmentPos)
+    UBool ok = FALSE;
+    UChar32 cp;
+    int32_t decompPos = 0;
+    UChar32 decompCp;
+    U16_NEXT(decomp, decompPos, decompLen, decompCp);
+
+    int32_t i = segmentPos;
+    while(i < segLen) {
+        U16_NEXT(segment, i, segLen, cp);
+
+        if (cp == decompCp) { // if equal, eat another cp from decomp
+
+            //if (PROGRESS) printf("  matches: %s\n", UToS(Tr(UnicodeString(cp))));
+
+            if (decompPos == decompLen) { // done, have all decomp characters!
+                temp.append(segment+i, segLen-i);
+                ok = TRUE;
+                break;
+            }
+            U16_NEXT(decomp, decompPos, decompLen, decompCp);
+        } else {
+            //if (PROGRESS) printf("  buffer: %s\n", UToS(Tr(UnicodeString(cp))));
+
+            // brute force approach
+            temp.append(cp);
+
+            /* TODO: optimize
+            // since we know that the classes are monotonically increasing, after zero
+            // e.g. 0 5 7 9 0 3
+            // we can do an optimization
+            // there are only a few cases that work: zero, less, same, greater
+            // if both classes are the same, we fail
+            // if the decomp class < the segment class, we fail
+
+            segClass = getClass(cp);
+            if (decompClass <= segClass) return null;
+            */
+        }
+    }
+    if (!ok)
+        return NULL; // we failed, characters left over
+
+    //if (PROGRESS) printf("Matches\n");
+
+    if (inputLen == temp.length()) {
+        fillinResult->put(UnicodeString(), new UnicodeString(), status);
+        return fillinResult; // succeed, but no remainder
+    }
+
+    // brute force approach
+    // check to make sure result is canonically equivalent
+    UnicodeString trial;
+    nfd.normalize(temp, trial, status);
+    if(U_FAILURE(status) || trial.compare(segment+segmentPos, segLen - segmentPos) != 0) {
+        return NULL;
+    }
+
+    return getEquivalents2(fillinResult, temp.getBuffer()+inputLen, temp.length()-inputLen, status);
+}
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_NORMALIZATION */
diff --git a/icu/source/common/chariter.cpp b/icu/source/common/chariter.cpp
new file mode 100644
index 0000000..a598bd6
--- /dev/null
+++ b/icu/source/common/chariter.cpp
@@ -0,0 +1,96 @@
+/*
+**********************************************************************
+*   Copyright (C) 1999-2004, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*/
+
+#include "unicode/chariter.h"
+
+U_NAMESPACE_BEGIN
+
+ForwardCharacterIterator::~ForwardCharacterIterator() {}
+ForwardCharacterIterator::ForwardCharacterIterator()
+: UObject()
+{}
+ForwardCharacterIterator::ForwardCharacterIterator(const ForwardCharacterIterator &other)
+: UObject(other)
+{}
+
+
+CharacterIterator::CharacterIterator()
+: textLength(0), pos(0), begin(0), end(0) {
+}
+
+CharacterIterator::CharacterIterator(int32_t length)
+: textLength(length), pos(0), begin(0), end(length) {
+    if(textLength < 0) {
+        textLength = end = 0;
+    }
+}
+
+CharacterIterator::CharacterIterator(int32_t length, int32_t position)
+: textLength(length), pos(position), begin(0), end(length) {
+    if(textLength < 0) {
+        textLength = end = 0;
+    }
+    if(pos < 0) {
+        pos = 0;
+    } else if(pos > end) {
+        pos = end;
+    }
+}
+
+CharacterIterator::CharacterIterator(int32_t length, int32_t textBegin, int32_t textEnd, int32_t position)
+: textLength(length), pos(position), begin(textBegin), end(textEnd) {
+    if(textLength < 0) {
+        textLength = 0;
+    }
+    if(begin < 0) {
+        begin = 0;
+    } else if(begin > textLength) {
+        begin = textLength;
+    }
+    if(end < begin) {
+        end = begin;
+    } else if(end > textLength) {
+        end = textLength;
+    }
+    if(pos < begin) {
+        pos = begin;
+    } else if(pos > end) {
+        pos = end;
+    }
+}
+
+CharacterIterator::CharacterIterator(const CharacterIterator &that) :
+ForwardCharacterIterator(that),
+textLength(that.textLength), pos(that.pos), begin(that.begin), end(that.end)
+{
+}
+
+CharacterIterator &
+CharacterIterator::operator=(const CharacterIterator &that) {
+    ForwardCharacterIterator::operator=(that);
+    textLength = that.textLength;
+    pos = that.pos;
+    begin = that.begin;
+    end = that.end;
+    return *this;
+}
+
+// implementing first[32]PostInc() directly in a subclass should be faster
+// but these implementations make subclassing a little easier
+UChar
+CharacterIterator::firstPostInc(void) {
+    setToStart();
+    return nextPostInc();
+}
+
+UChar32
+CharacterIterator::first32PostInc(void) {
+    setToStart();
+    return next32PostInc();
+}
+
+U_NAMESPACE_END
diff --git a/icu/source/common/charstr.h b/icu/source/common/charstr.h
new file mode 100644
index 0000000..3bb11cb
--- /dev/null
+++ b/icu/source/common/charstr.h
@@ -0,0 +1,88 @@
+/*
+**********************************************************************
+*   Copyright (c) 2001-2004, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*   Date        Name        Description
+*   11/19/2001  aliu        Creation.
+**********************************************************************
+*/
+
+#ifndef CHARSTRING_H
+#define CHARSTRING_H
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+#include "unicode/unistr.h"
+#include "cmemory.h"
+
+//--------------------------------------------------------------------
+// class CharString
+//
+// This is a tiny wrapper class that is used internally to make a
+// UnicodeString look like a const char*.  It can be allocated on the
+// stack.  It only creates a heap buffer if it needs to.
+//--------------------------------------------------------------------
+
+U_NAMESPACE_BEGIN
+
+class U_COMMON_API CharString : public UMemory {
+public:
+
+#if !UCONFIG_NO_CONVERSION
+    // Constructor
+    //     @param  str    The unicode string to be converted to char *
+    //     @param  codepage   The char * code page.  ""   for invariant conversion.
+    //                                               NULL for default code page.
+//    inline CharString(const UnicodeString& str, const char *codepage);
+#endif
+
+    inline CharString(const UnicodeString& str);
+    inline ~CharString();
+    inline operator const char*() const { return ptr; }
+
+private:
+    char buf[128];
+    char* ptr;
+
+    CharString(const CharString &other); // forbid copying of this class
+    CharString &operator=(const CharString &other); // forbid copying of this class
+};
+
+#if !UCONFIG_NO_CONVERSION
+
+// PLEASE DON'T USE THIS FUNCTION.
+// We don't want the static dependency on conversion or the performance hit that comes from a codepage conversion.
+/*
+inline CharString::CharString(const UnicodeString& str, const char *codepage) {
+    int32_t    len;
+    ptr = buf;
+    len = str.extract(0, 0x7FFFFFFF, buf ,sizeof(buf)-1, codepage);
+    if (len >= (int32_t)(sizeof(buf)-1)) {
+        ptr = (char *)uprv_malloc(len+1);
+        str.extract(0, 0x7FFFFFFF, ptr, len+1, codepage);
+    }
+}*/
+
+#endif
+
+inline CharString::CharString(const UnicodeString& str) {
+    int32_t    len;
+    ptr = buf;
+    len = str.extract(0, 0x7FFFFFFF, buf, (int32_t)(sizeof(buf)-1), US_INV);
+    if (len >= (int32_t)(sizeof(buf)-1)) {
+        ptr = (char *)uprv_malloc(len+1);
+        str.extract(0, 0x7FFFFFFF, ptr, len+1, US_INV);
+    }
+}
+
+inline CharString::~CharString() {
+    if (ptr != buf) {
+        uprv_free(ptr);
+    }
+}
+
+U_NAMESPACE_END
+
+#endif
+//eof
diff --git a/icu/source/common/cmemory.c b/icu/source/common/cmemory.c
new file mode 100644
index 0000000..0f93f36
--- /dev/null
+++ b/icu/source/common/cmemory.c
@@ -0,0 +1,124 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 2002-2003, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+* File cmemory.c      ICU Heap allocation.
+*                     All ICU heap allocation, both for C and C++ new of ICU
+*                     class types, comes through these functions.
+*
+*                     If you have a need to replace ICU allocation, this is the
+*                     place to do it.
+*
+*                     Note that uprv_malloc(0) returns a non-NULL pointer, and
+*                     that a subsequent free of that pointer value is a NOP.
+*
+******************************************************************************
+*/
+#include "unicode/uclean.h"
+#include "cmemory.h"
+#include <stdlib.h>
+
+/* uprv_malloc(0) returns a pointer to this read-only data. */                
+static const int32_t zeroMem[] = {0, 0, 0, 0, 0, 0};
+
+/* Function Pointers for user-supplied heap functions  */
+static const void     *pContext;
+static UMemAllocFn    *pAlloc;
+static UMemReallocFn  *pRealloc;
+static UMemFreeFn     *pFree;
+
+/* Flag indicating whether any heap allocations have happened.
+ *   Used to prevent changing out the heap functions after allocations have been made */
+static UBool   gHeapInUse;
+
+U_CAPI void * U_EXPORT2
+uprv_malloc(size_t s) {
+    if (s > 0) {
+        gHeapInUse = TRUE;
+        if (pAlloc) {
+            return (*pAlloc)(pContext, s);
+        } else {
+            return malloc(s);
+        }
+    } else {
+        return (void *)zeroMem;
+    }
+}
+
+U_CAPI void * U_EXPORT2
+uprv_realloc(void * buffer, size_t size) {
+    if (buffer == zeroMem) {
+        return uprv_malloc(size);
+    } else if (size == 0) {
+        if (pFree) {
+            (*pFree)(pContext, buffer);
+        } else {
+            free(buffer);
+        }
+        return (void *)zeroMem;
+    } else {
+        gHeapInUse = TRUE;
+        if (pRealloc) {
+            return (*pRealloc)(pContext, buffer, size);
+        } else {
+            return realloc(buffer, size);
+        }
+    }
+}
+
+U_CAPI void U_EXPORT2
+uprv_free(void *buffer) {
+    if (buffer != zeroMem) {
+        if (pFree) {
+            (*pFree)(pContext, buffer);
+        } else {
+            free(buffer);
+        }
+    }
+}
+
+U_CAPI void U_EXPORT2
+u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMemFreeFn *f,  UErrorCode *status)
+{
+    if (U_FAILURE(*status)) {
+        return;
+    }
+    if (a==NULL || r==NULL || f==NULL) {
+        *status = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    if (gHeapInUse) {
+        *status = U_INVALID_STATE_ERROR;
+        return;
+    }
+    pContext  = context;
+    pAlloc    = a;
+    pRealloc  = r;
+    pFree     = f;
+}
+
+
+U_CFUNC UBool cmemory_cleanup(void) {
+    pContext   = NULL;
+    pAlloc     = NULL;
+    pRealloc   = NULL;
+    pFree      = NULL;
+    gHeapInUse = FALSE;
+    return TRUE;
+}
+
+
+/*
+ *   gHeapInUse
+ *       Return True if ICU has allocated any memory.
+ *       Used by u_SetMutexFunctions() and similar to verify that ICU has not
+ *               been used, that it is in a pristine initial state.
+ */
+U_CFUNC UBool cmemory_inUse() {
+    return gHeapInUse;
+}
+
diff --git a/icu/source/common/cmemory.h b/icu/source/common/cmemory.h
new file mode 100644
index 0000000..0c525d0
--- /dev/null
+++ b/icu/source/common/cmemory.h
@@ -0,0 +1,362 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1997-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+* File CMEMORY.H
+*
+*  Contains stdlib.h/string.h memory functions
+*
+* @author       Bertrand A. Damiba
+*
+* Modification History:
+*
+*   Date        Name        Description
+*   6/20/98     Bertrand    Created.
+*  05/03/99     stephen     Changed from functions to macros.
+*
+******************************************************************************
+*/
+
+#ifndef CMEMORY_H
+#define CMEMORY_H
+
+#include "unicode/utypes.h"
+#include "unicode/localpointer.h"
+#include <stddef.h>
+#include <string.h>
+
+
+#define uprv_memcpy(dst, src, size) U_STANDARD_CPP_NAMESPACE memcpy(dst, src, size)
+#define uprv_memmove(dst, src, size) U_STANDARD_CPP_NAMESPACE memmove(dst, src, size)
+#define uprv_memset(buffer, mark, size) U_STANDARD_CPP_NAMESPACE memset(buffer, mark, size)
+#define uprv_memcmp(buffer1, buffer2, size) U_STANDARD_CPP_NAMESPACE memcmp(buffer1, buffer2,size)
+
+U_CAPI void * U_EXPORT2
+uprv_malloc(size_t s);
+
+U_CAPI void * U_EXPORT2
+uprv_realloc(void *mem, size_t size);
+
+U_CAPI void U_EXPORT2
+uprv_free(void *mem);
+
+/**
+ * This should align the memory properly on any machine.
+ * This is very useful for the safeClone functions.
+ */
+typedef union {
+    long    t1;
+    double  t2;
+    void   *t3;
+} UAlignedMemory;
+
+/**
+ * Get the least significant bits of a pointer (a memory address).
+ * For example, with a mask of 3, the macro gets the 2 least significant bits,
+ * which will be 0 if the pointer is 32-bit (4-byte) aligned.
+ *
+ * ptrdiff_t is the most appropriate integer type to cast to.
+ * size_t should work too, since on most (or all?) platforms it has the same
+ * width as ptrdiff_t.
+ */
+#define U_POINTER_MASK_LSB(ptr, mask) (((ptrdiff_t)(char *)(ptr)) & (mask))
+
+/**
+ * Get the amount of bytes that a pointer is off by from
+ * the previous UAlignedMemory-aligned pointer.
+ */
+#define U_ALIGNMENT_OFFSET(ptr) U_POINTER_MASK_LSB(ptr, sizeof(UAlignedMemory) - 1)
+
+/**
+ * Get the amount of bytes to add to a pointer
+ * in order to get the next UAlignedMemory-aligned address.
+ */
+#define U_ALIGNMENT_OFFSET_UP(ptr) (sizeof(UAlignedMemory) - U_ALIGNMENT_OFFSET(ptr))
+
+/**
+  *  Indicate whether the ICU allocation functions have been used.
+  *  This is used to determine whether ICU is in an initial, unused state.
+  */
+U_CFUNC UBool 
+cmemory_inUse(void);
+
+/**
+  *  Heap clean up function, called from u_cleanup()
+  *    Clears any user heap functions from u_setMemoryFunctions()
+  *    Does NOT deallocate any remaining allocated memory.
+  */
+U_CFUNC UBool 
+cmemory_cleanup(void);
+
+#ifdef XP_CPLUSPLUS
+
+U_NAMESPACE_BEGIN
+
+/**
+ * "Smart pointer" class, deletes memory via uprv_free().
+ * For most methods see the LocalPointerBase base class.
+ * Adds operator[] for array item access.
+ *
+ * @see LocalPointerBase
+ */
+template<typename T>
+class LocalMemory : public LocalPointerBase<T> {
+public:
+    /**
+     * Constructor takes ownership.
+     * @param p simple pointer to an array of T items that is adopted
+     */
+    explicit LocalMemory(T *p=NULL) : LocalPointerBase<T>(p) {}
+    /**
+     * Destructor deletes the memory it owns.
+     */
+    ~LocalMemory() {
+        uprv_free(LocalPointerBase<T>::ptr);
+    }
+    /**
+     * Deletes the array it owns,
+     * and adopts (takes ownership of) the one passed in.
+     * @param p simple pointer to an array of T items that is adopted
+     */
+    void adoptInstead(T *p) {
+        uprv_free(LocalPointerBase<T>::ptr);
+        LocalPointerBase<T>::ptr=p;
+    }
+    /**
+     * Deletes the array it owns, allocates a new one and reset its bytes to 0.
+     * Returns the new array pointer.
+     * If the allocation fails, then the current array is unchanged and
+     * this method returns NULL.
+     * @param newCapacity must be >0
+     * @return the allocated array pointer, or NULL if the allocation failed
+     */
+    inline T *allocateInsteadAndReset(int32_t newCapacity=1);
+    /**
+     * Deletes the array it owns and allocates a new one, copying length T items.
+     * Returns the new array pointer.
+     * If the allocation fails, then the current array is unchanged and
+     * this method returns NULL.
+     * @param newCapacity must be >0
+     * @param length number of T items to be copied from the old array to the new one;
+     *               must be no more than the capacity of the old array,
+     *               which the caller must track because the LocalMemory does not track it
+     * @return the allocated array pointer, or NULL if the allocation failed
+     */
+    inline T *allocateInsteadAndCopy(int32_t newCapacity=1, int32_t length=0);
+    /**
+     * Array item access (writable).
+     * No index bounds check.
+     * @param i array index
+     * @return reference to the array item
+     */
+    T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
+};
+
+/**
+ * Simple array/buffer management class using uprv_malloc() and uprv_free().
+ * Provides an internal array with fixed capacity. Can alias another array
+ * or allocate one.
+ * Unlike LocalMemory and LocalArray, this class never adopts
+ * (takes ownership of) another array.
+ */
+template<typename T, int32_t stackCapacity>
+class MaybeStackArray {
+public:
+    /**
+     * Default constructor initializes with internal T[stackCapacity] buffer.
+     */
+    MaybeStackArray() : needToRelease(FALSE), capacity(stackCapacity), ptr(stackArray) {}
+    /**
+     * Destructor deletes the array (if owned).
+     */
+    ~MaybeStackArray() { releaseArray(); }
+    /**
+     * Returns the array capacity (number of T items).
+     * @return array capacity
+     */
+    int32_t getCapacity() const { return capacity; }
+    /**
+     * Access without ownership change.
+     * @return the array pointer
+     */
+    T *getAlias() const { return ptr; }
+    /**
+     * Returns the array limit. Simple convenience method.
+     * @return getAlias()+getCapacity()
+     */
+    T *getArrayLimit() const { return getAlias()+capacity; }
+    /**
+     * Access without ownership change. Same as getAlias().
+     * A class instance can be used directly in expressions that take a T *.
+     * @return the array pointer
+     */
+    operator T *() const { return ptr; }
+    /**
+     * Array item access (writable).
+     * No index bounds check.
+     * @param i array index
+     * @return reference to the array item
+     */
+    T &operator[](ptrdiff_t i) { return ptr[i]; }
+    /**
+     * Deletes the array (if owned) and aliases another one, no transfer of ownership.
+     * If the arguments are illegal, then the current array is unchanged.
+     * @param otherArray must not be NULL
+     * @param otherCapacity must be >0
+     */
+    void aliasInstead(T *otherArray, int32_t otherCapacity) {
+        if(otherArray!=NULL && otherCapacity>0) {
+            releaseArray();
+            ptr=otherArray;
+            capacity=otherCapacity;
+            needToRelease=FALSE;
+        }
+    };
+    /**
+     * Deletes the array (if owned) and allocates a new one, copying length T items.
+     * Returns the new array pointer.
+     * If the allocation fails, then the current array is unchanged and
+     * this method returns NULL.
+     * @param newCapacity can be less than or greater than the current capacity;
+     *                    must be >0
+     * @param length number of T items to be copied from the old array to the new one
+     * @return the allocated array pointer, or NULL if the allocation failed
+     */
+    inline T *resize(int32_t newCapacity, int32_t length=0);
+    /**
+     * Gives up ownership of the array if owned, or else clones it,
+     * copying length T items; resets itself to the internal stack array.
+     * Returns NULL if the allocation failed.
+     * @param length number of T items to copy when cloning,
+     *        and capacity of the clone when cloning
+     * @param resultCapacity will be set to the returned array's capacity (output-only)
+     * @return the array pointer;
+     *         caller becomes responsible for deleting the array
+     * @draft ICU 4.4
+     */
+    inline T *orphanOrClone(int32_t length, int32_t &resultCapacity);
+private:
+    UBool needToRelease;
+    int32_t capacity;
+    T *ptr;
+    T stackArray[stackCapacity];
+    void releaseArray() {
+        if(needToRelease) {
+            uprv_free(ptr);
+        }
+    }
+    /* No comparison operators with other MaybeStackArray's. */
+    bool operator==(const MaybeStackArray & /*other*/) {return FALSE;};
+    bool operator!=(const MaybeStackArray & /*other*/) {return TRUE;};
+    /* No ownership transfer: No copy constructor, no assignment operator. */
+    MaybeStackArray(const MaybeStackArray & /*other*/) {};
+    void operator=(const MaybeStackArray & /*other*/) {};
+
+    // No heap allocation. Use only on the stack.
+    //   (Declaring these functions private triggers a cascade of problems:
+    //      MSVC insists on exporting an instantiation of MaybeStackArray, which
+    //      requires that all functions be defined.
+    //      An empty implementation of new() is rejected, it must return a value.
+    //      Returning NULL is rejected by gcc for operator new.
+    //      The expedient thing is just not to override operator new.
+    //      While relatively pointless, heap allocated instances will function.
+    // static void * U_EXPORT2 operator new(size_t size); 
+    // static void * U_EXPORT2 operator new[](size_t size);
+#if U_HAVE_PLACEMENT_NEW
+    // static void * U_EXPORT2 operator new(size_t, void *ptr);
+#endif
+};
+
+template<typename T>
+inline T *LocalMemory<T>::allocateInsteadAndReset(int32_t newCapacity) {
+    if(newCapacity>0) {
+        T *p=(T *)uprv_malloc(newCapacity*sizeof(T));
+        if(p!=NULL) {
+            uprv_memset(p, 0, newCapacity*sizeof(T));
+            uprv_free(LocalPointerBase<T>::ptr);
+            LocalPointerBase<T>::ptr=p;
+        }
+        return p;
+    } else {
+        return NULL;
+    }
+}
+
+
+template<typename T>
+inline T *LocalMemory<T>::allocateInsteadAndCopy(int32_t newCapacity, int32_t length) {
+    if(newCapacity>0) {
+        T *p=(T *)uprv_malloc(newCapacity*sizeof(T));
+        if(p!=NULL) {
+            if(length>0) {
+                if(length>newCapacity) {
+                    length=newCapacity;
+                }
+                uprv_memcpy(p, LocalPointerBase<T>::ptr, length*sizeof(T));
+            }
+            uprv_free(LocalPointerBase<T>::ptr);
+            LocalPointerBase<T>::ptr=p;
+        }
+        return p;
+    } else {
+        return NULL;
+    }
+}
+
+template<typename T, int32_t stackCapacity>
+inline T *MaybeStackArray<T, stackCapacity>::resize(int32_t newCapacity, int32_t length) {
+    if(newCapacity>0) {
+        T *p=(T *)uprv_malloc(newCapacity*sizeof(T));
+        if(p!=NULL) {
+            if(length>0) {
+                if(length>capacity) {
+                    length=capacity;
+                }
+                if(length>newCapacity) {
+                    length=newCapacity;
+                }
+                uprv_memcpy(p, ptr, length*sizeof(T));
+            }
+            releaseArray();
+            ptr=p;
+            capacity=newCapacity;
+            needToRelease=TRUE;
+        }
+        return p;
+    } else {
+        return NULL;
+    }
+}
+
+template<typename T, int32_t stackCapacity>
+inline T *MaybeStackArray<T, stackCapacity>::orphanOrClone(int32_t length, int32_t &resultCapacity) {
+    T *p;
+    if(needToRelease) {
+        p=ptr;
+    } else if(length<=0) {
+        return NULL;
+    } else {
+        if(length>capacity) {
+            length=capacity;
+        }
+        p=(T *)uprv_malloc(length*sizeof(T));
+        if(p==NULL) {
+            return NULL;
+        }
+        uprv_memcpy(p, ptr, length*sizeof(T));
+    }
+    resultCapacity=length;
+    ptr=stackArray;
+    capacity=stackCapacity;
+    needToRelease=FALSE;
+    return p;
+}
+
+U_NAMESPACE_END
+
+#endif  /* XP_CPLUSPLUS */
+#endif  /* CMEMORY_H */
diff --git a/icu/source/common/common.rc b/icu/source/common/common.rc
new file mode 100644
index 0000000..e0820bb
--- /dev/null
+++ b/icu/source/common/common.rc
@@ -0,0 +1,108 @@
+// Do not edit with Microsoft Developer Studio Resource Editor.
+//   It will permanently substitute version numbers that are intended to be
+//   picked up by the pre-processor during each build.
+// Copyright (c) 2001-2010 International Business Machines
+// Corporation and others. All Rights Reserved.
+//
+#include "msvcres.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <winresrc.h>
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// 
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#pragma code_page(1252)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "msvcres.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#include <winresrc.h>\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#define STR(s) #s
+#define CommaVersionString(a, b, c, d) STR(a) ", " STR(b) ", " STR(c) ", " STR(d) "\0"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION U_ICU_VERSION_MAJOR_NUM, U_ICU_VERSION_MINOR_NUM, U_ICU_VERSION_PATCHLEVEL_NUM, U_ICU_VERSION_BUILDLEVEL_NUM
+ PRODUCTVERSION U_ICU_VERSION_MAJOR_NUM, U_ICU_VERSION_MINOR_NUM, U_ICU_VERSION_PATCHLEVEL_NUM, U_ICU_VERSION_BUILDLEVEL_NUM
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "00000000"
+        BEGIN
+            VALUE "Comments", ICU_WEBSITE "\0"
+            VALUE "CompanyName", ICU_COMPANY "\0"
+            VALUE "FileDescription", ICU_PRODUCT_PREFIX " Common DLL\0"
+            VALUE "FileVersion",  CommaVersionString(U_ICU_VERSION_MAJOR_NUM, U_ICU_VERSION_MINOR_NUM, U_ICU_VERSION_PATCHLEVEL_NUM, U_ICU_VERSION_BUILDLEVEL_NUM)
+            VALUE "LegalCopyright", U_COPYRIGHT_STRING "\0"
+#ifdef _DEBUG
+            VALUE "OriginalFilename", "icuuc" U_ICU_VERSION_SHORT "d.dll\0"
+#else
+            VALUE "OriginalFilename", "icuuc" U_ICU_VERSION_SHORT ".dll\0"
+#endif
+            VALUE "PrivateBuild", "\0"
+            VALUE "ProductName", ICU_PRODUCT "\0"
+            VALUE "ProductVersion", CommaVersionString(U_ICU_VERSION_MAJOR_NUM, U_ICU_VERSION_MINOR_NUM, U_ICU_VERSION_PATCHLEVEL_NUM, U_ICU_VERSION_BUILDLEVEL_NUM)
+            VALUE "SpecialBuild", "\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x000, 0000
+    END
+END
+
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/icu/source/common/common.vcproj b/icu/source/common/common.vcproj
new file mode 100644
index 0000000..cc02a6d
--- /dev/null
+++ b/icu/source/common/common.vcproj
@@ -0,0 +1,4650 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="common"
+	ProjectGUID="{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\..\..\lib"
+			IntermediateDirectory=".\x86\Release"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="1"
+				TypeLibraryName=".\..\..\lib\icuuc.tlb"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;U_COMMON_IMPLEMENTATION"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				DisableLanguageExtensions="true"
+				TreatWChar_tAsBuiltInType="true"
+				PrecompiledHeaderFile=".\x86\Release/common.pch"
+				AssemblerListingLocation=".\x86\Release/"
+				ObjectFile=".\x86\Release/"
+				ProgramDataBaseFileName=".\x86\Release/"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="..\..\bin\icuuc44.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				ProgramDatabaseFile=".\..\..\lib\icuuc.pdb"
+				EnableCOMDATFolding="2"
+				BaseAddress="0x4a800000"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				ImportLibrary="..\..\lib\icuuc.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\..\..\lib"
+			IntermediateDirectory=".\x86\Debug"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="_DEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="1"
+				TypeLibraryName=".\..\..\lib\icuucd.tlb"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;U_COMMON_IMPLEMENTATION;RBBI_DEBUG"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				BufferSecurityCheck="true"
+				DisableLanguageExtensions="true"
+				TreatWChar_tAsBuiltInType="true"
+				PrecompiledHeaderFile=".\x86\Debug/common.pch"
+				AssemblerListingLocation=".\x86\Debug/"
+				ObjectFile=".\x86\Debug/"
+				ProgramDataBaseFileName=".\x86\Debug/"
+				BrowseInformation="1"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="..\..\bin\icuuc44d.dll"
+				LinkIncremental="2"
+				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\..\..\lib\icuucd.pdb"
+				BaseAddress="0x4a800000"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				ImportLibrary="..\..\lib\icuucd.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+				UseFAT32Workaround="true"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory=".\x64\Release"
+			IntermediateDirectory=".\x64\Release"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="3"
+				TypeLibraryName=".\..\..\lib64\icuuc.tlb"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				PreprocessorDefinitions="WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;U_COMMON_IMPLEMENTATION"
+				StringPooling="true"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				DisableLanguageExtensions="true"
+				TreatWChar_tAsBuiltInType="true"
+				PrecompiledHeaderFile=".\x64\Release/common.pch"
+				AssemblerListingLocation=".\x64\Release/"
+				ObjectFile=".\x64\Release/"
+				ProgramDataBaseFileName=".\x64\Release/"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="..\..\bin64\icuuc44.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				ProgramDatabaseFile=".\..\..\lib64\icuuc.pdb"
+				EnableCOMDATFolding="2"
+				BaseAddress="0x4a800000"
+				ImportLibrary="..\..\lib64\icuuc.lib"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory=".\x64\Debug"
+			IntermediateDirectory=".\x64\Debug"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="_DEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="3"
+				TypeLibraryName=".\..\..\lib64\icuucd.tlb"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN64;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;U_COMMON_IMPLEMENTATION;RBBI_DEBUG"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				BufferSecurityCheck="true"
+				DisableLanguageExtensions="true"
+				TreatWChar_tAsBuiltInType="true"
+				PrecompiledHeaderFile=".\x64\Debug/common.pch"
+				AssemblerListingLocation=".\x64\Debug/"
+				ObjectFile=".\x64\Debug/"
+				ProgramDataBaseFileName=".\x64\Debug/"
+				BrowseInformation="1"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="..\..\bin64\icuuc44d.dll"
+				LinkIncremental="2"
+				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile=".\..\..\lib64\icuucd.pdb"
+				BaseAddress="0x4a800000"
+				ImportLibrary="..\..\lib64\icuucd.lib"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+				UseFAT32Workaround="true"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="bidi"
+			>
+			<File
+				RelativePath=".\ubidi.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\ubidi.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\ubidi_props.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ubidi_props.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ubidiimp.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ubidiln.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ubidiwrt.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ushape.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\ushape.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+		</Filter>
+		<Filter
+			Name="break iteration"
+			>
+			<File
+				RelativePath=".\brkeng.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\brkeng.h"
+				>
+			</File>
+			<File
+				RelativePath=".\brkiter.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\brkiter.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\dbbi.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\dictbe.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\dictbe.h"
+				>
+			</File>
+			<File
+				RelativePath=".\rbbi.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\rbbi.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\rbbidata.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\rbbidata.h"
+				>
+			</File>
+			<File
+				RelativePath=".\rbbinode.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\rbbinode.h"
+				>
+			</File>
+			<File
+				RelativePath=".\rbbirb.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\rbbirb.h"
+				>
+			</File>
+			<File
+				RelativePath=".\rbbirpt.h"
+				>
+			</File>
+			<File
+				RelativePath=".\rbbiscan.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\rbbiscan.h"
+				>
+			</File>
+			<File
+				RelativePath=".\rbbisetb.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\rbbisetb.h"
+				>
+			</File>
+			<File
+				RelativePath=".\rbbistbl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\rbbitblb.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\rbbitblb.h"
+				>
+			</File>
+			<File
+				RelativePath=".\triedict.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\triedict.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ubrk.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\ubrk.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\ubrkimpl.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="collation"
+			>
+			<File
+				RelativePath=".\ucol_swp.cpp"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\i18n"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\i18n"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\i18n"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories="..\i18n"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\ucol_swp.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="collections"
+			>
+			<File
+				RelativePath=".\hash.h"
+				>
+			</File>
+			<File
+				RelativePath=".\propsvec.c"
+				>
+			</File>
+			<File
+				RelativePath=".\propsvec.h"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\strenum.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\uarrsort.c"
+				>
+			</File>
+			<File
+				RelativePath=".\uarrsort.h"
+				>
+			</File>
+			<File
+				RelativePath=".\uenum.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\uenum.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\uenumimp.h"
+				>
+			</File>
+			<File
+				RelativePath=".\uhash.c"
+				>
+			</File>
+			<File
+				RelativePath=".\uhash.h"
+				>
+			</File>
+			<File
+				RelativePath=".\uhash_us.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\ulist.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ulist.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ustack.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\ustrenum.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\ustrenum.h"
+				>
+			</File>
+			<File
+				RelativePath=".\utrie.c"
+				>
+			</File>
+			<File
+				RelativePath=".\utrie.h"
+				>
+			</File>
+			<File
+				RelativePath=".\utrie2.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\utrie2.h"
+				>
+			</File>
+			<File
+				RelativePath=".\utrie2_builder.c"
+				>
+			</File>
+			<File
+				RelativePath=".\utrie2_impl.h"
+				>
+			</File>
+			<File
+				RelativePath=".\uvector.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\uvector.h"
+				>
+			</File>
+			<File
+				RelativePath=".\uvectr32.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\uvectr32.h"
+				>
+			</File>
+			<File
+				RelativePath=".\uvectr64.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\uvectr64.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="configuration"
+			>
+			<File
+				RelativePath=".\common.rc"
+				>
+			</File>
+			<File
+				RelativePath=".\cpputils.h"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\docmain.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\errorcode.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\errorcode.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\icudataver.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\icudataver.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\locmap.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\locmap.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mutex.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mutex.h"
+				>
+			</File>
+			<File
+				RelativePath=".\putil.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\putil.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\putilimp.h"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\pwin32.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\std_string.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\uassert.h"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\uconfig.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\udeprctd.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\udraft.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\uintrnal.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\umachine.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\umath.c"
+				>
+			</File>
+			<File
+				RelativePath=".\umutex.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\umutex.h"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\uobslete.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\urename.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\usystem.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\utrace.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\utrace.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\utracimp.h"
+				>
+			</File>
+			<File
+				RelativePath=".\utypes.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\utypes.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\uvernum.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\uversion.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\wintz.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\wintz.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="conversion"
+			>
+			<File
+				RelativePath=".\ucnv.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\ucnv.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\ucnv2022.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnv_bld.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnv_bld.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnv_cb.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\ucnv_cb.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\ucnv_cnv.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnv_cnv.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnv_err.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\ucnv_err.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\ucnv_ext.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnv_ext.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnv_imp.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnv_io.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnv_io.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnv_lmb.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnv_set.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnv_u16.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnv_u32.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnv_u7.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnv_u8.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnvbocu.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnvdisp.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnvhz.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnvisci.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnvlat1.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnvmbcs.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnvmbcs.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnvscsu.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucnvsel.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\ucnvsel.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+		</Filter>
+		<Filter
+			Name="data &amp; memory"
+			>
+			<File
+				RelativePath=".\cmemory.c"
+				>
+			</File>
+			<File
+				RelativePath=".\cmemory.h"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\localpointer.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\uclean.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\ucln.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ucln_cmn.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\ucln_cmn.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ucln_imp.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ucmndata.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucmndata.h"
+				>
+			</File>
+			<File
+				RelativePath=".\udata.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\udata.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\udatamem.c"
+				>
+			</File>
+			<File
+				RelativePath=".\udatamem.h"
+				>
+			</File>
+			<File
+				RelativePath=".\udataswp.c"
+				>
+			</File>
+			<File
+				RelativePath=".\udataswp.h"
+				>
+			</File>
+			<File
+				RelativePath=".\uinit.c"
+				>
+			</File>
+			<File
+				RelativePath=".\umapfile.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableLanguageExtensions="false"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\umapfile.h"
+				>
+			</File>
+			<File
+				RelativePath=".\uobject.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\uobject.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+		</Filter>
+		<Filter
+			Name="formatting"
+			>
+			<File
+				RelativePath=".\dtintrv.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\dtintrv.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\parseerr.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\parsepos.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\parsepos.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\umisc.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\ustrfmt.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ustrfmt.h"
+				>
+			</File>
+			<File
+				RelativePath=".\util.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\util.h"
+				>
+			</File>
+			<File
+				RelativePath=".\util_props.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="idna"
+			Filter="*.c,*.h"
+			>
+			<File
+				RelativePath=".\punycode.c"
+				>
+			</File>
+			<File
+				RelativePath=".\punycode.h"
+				>
+			</File>
+			<File
+				RelativePath=".\uidna.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\uidna.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+		</Filter>
+		<Filter
+			Name="locales &amp; resources"
+			>
+			<File
+				RelativePath=".\locavailable.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\locbased.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\locbased.h"
+				>
+			</File>
+			<File
+				RelativePath=".\locdispnames.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\locid.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\locid.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\loclikely.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\locresdata.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\locutil.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\locutil.h"
+				>
+			</File>
+			<File
+				RelativePath=".\resbund.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\resbund.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\resbund_cnv.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\ucat.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\ucat.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\uloc.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\uloc.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\uloc_tag.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ulocimp.h"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\ures.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\ures_cnv.c"
+				>
+			</File>
+			<File
+				RelativePath=".\uresbund.c"
+				>
+			</File>
+			<File
+				RelativePath=".\uresdata.c"
+				>
+			</File>
+			<File
+				RelativePath=".\uresdata.h"
+				>
+			</File>
+			<File
+				RelativePath=".\uresimp.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ureslocs.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="normalization"
+			>
+			<File
+				RelativePath=".\caniter.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\caniter.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\filterednormalizer2.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\normalizer2.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\normalizer2.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\normalizer2impl.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\normalizer2impl.h"
+				>
+			</File>
+			<File
+				RelativePath=".\normlzr.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\normlzr.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unorm.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\unorm.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\unorm2.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unorm_it.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unorm_it.h"
+				>
+			</File>
+			<File
+				RelativePath=".\unormcmp.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unormimp.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="properties &amp; sets"
+			>
+			<File
+				RelativePath=".\bmpset.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\bmpset.h"
+				>
+			</File>
+			<File
+				RelativePath=".\propname.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\propname.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ruleiter.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\ruleiter.h"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\symtable.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\ucase.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ucase.h"
+				>
+			</File>
+			<File
+				RelativePath=".\uchar.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\uchar.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unames.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unifilt.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\unifilt.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unifunct.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\unifunct.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\unimatch.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\uniset.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\uniset.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\uniset_props.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unisetspan.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unisetspan.h"
+				>
+			</File>
+			<File
+				RelativePath=".\uprops.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\uprops.h"
+				>
+			</File>
+			<File
+				RelativePath=".\usc_impl.c"
+				>
+			</File>
+			<File
+				RelativePath=".\usc_impl.h"
+				>
+			</File>
+			<File
+				RelativePath=".\uscript.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\uscript.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\uset.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\uset.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\uset_imp.h"
+				>
+			</File>
+			<File
+				RelativePath=".\uset_props.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\usetiter.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\usetiter.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+		</Filter>
+		<Filter
+			Name="registration"
+			>
+			<File
+				RelativePath=".\icuplug.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\icuplug.h"
+				>
+			</File>
+			<File
+				RelativePath=".\icuplugimp.h"
+				>
+			</File>
+			<File
+				RelativePath=".\serv.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\serv.h"
+				>
+			</File>
+			<File
+				RelativePath=".\servlk.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\servlkf.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\servloc.h"
+				>
+			</File>
+			<File
+				RelativePath=".\servls.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\servnotf.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\servnotf.h"
+				>
+			</File>
+			<File
+				RelativePath=".\servrbf.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\servslkf.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="sprep"
+			>
+			<File
+				RelativePath=".\sprpimpl.h"
+				>
+			</File>
+			<File
+				RelativePath=".\usprep.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\usprep.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+		</Filter>
+		<Filter
+			Name="strings"
+			>
+			<File
+				RelativePath=".\bytestream.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\bytestream.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\chariter.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\chariter.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\charstr.h"
+				>
+			</File>
+			<File
+				RelativePath=".\cstring.c"
+				>
+			</File>
+			<File
+				RelativePath=".\cstring.h"
+				>
+			</File>
+			<File
+				RelativePath=".\cwchar.c"
+				>
+			</File>
+			<File
+				RelativePath=".\cwchar.h"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\rep.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\schriter.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\schriter.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\stringpiece.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\stringpiece.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\ucasemap.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\ucasemap.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\uchriter.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\uchriter.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\uinvchar.c"
+				>
+			</File>
+			<File
+				RelativePath=".\uinvchar.h"
+				>
+			</File>
+			<File
+				RelativePath=".\uiter.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\uiter.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unistr.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\unistr.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unistr_case.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unistr_cnv.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unistr_props.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\urep.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\ustr_cnv.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ustr_cnv.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ustr_imp.h"
+				>
+			</File>
+			<File
+				RelativePath=".\ustr_wcs.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ustrcase.c"
+				>
+			</File>
+			<File
+				RelativePath=".\ustring.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\ustring.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\ustrtrns.c"
+				>
+			</File>
+			<File
+				RelativePath=".\utext.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\utext.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\utf.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\utf16.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\utf32.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\unicode\utf8.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\utf_impl.c"
+				>
+			</File>
+			<File
+				RelativePath=".\unicode\utf_old.h"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
+						Outputs="..\..\include\unicode\$(InputFileName)"
+					/>
+				</FileConfiguration>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/icu/source/common/cpputils.h b/icu/source/common/cpputils.h
new file mode 100644
index 0000000..e423900
--- /dev/null
+++ b/icu/source/common/cpputils.h
@@ -0,0 +1,95 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1997-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*   file name:  cpputils.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*/
+
+#ifndef CPPUTILS_H
+#define CPPUTILS_H
+
+#include "unicode/utypes.h"
+#include "unicode/unistr.h"
+#include "cmemory.h"
+
+/*==========================================================================*/
+/* Array copy utility functions */
+/*==========================================================================*/
+
+static
+inline void uprv_arrayCopy(const double* src, double* dst, int32_t count)
+{ uprv_memcpy(dst, src, (size_t)(count * sizeof(*src))); }
+
+static
+inline void uprv_arrayCopy(const double* src, int32_t srcStart,
+              double* dst, int32_t dstStart, int32_t count)
+{ uprv_memcpy(dst+dstStart, src+srcStart, (size_t)(count * sizeof(*src))); }
+
+static
+inline void uprv_arrayCopy(const int8_t* src, int8_t* dst, int32_t count)
+    { uprv_memcpy(dst, src, (size_t)(count * sizeof(*src))); }
+
+static
+inline void uprv_arrayCopy(const int8_t* src, int32_t srcStart,
+              int8_t* dst, int32_t dstStart, int32_t count)
+{ uprv_memcpy(dst+dstStart, src+srcStart, (size_t)(count * sizeof(*src))); }
+
+static
+inline void uprv_arrayCopy(const int16_t* src, int16_t* dst, int32_t count)
+{ uprv_memcpy(dst, src, (size_t)(count * sizeof(*src))); }
+
+static
+inline void uprv_arrayCopy(const int16_t* src, int32_t srcStart,
+              int16_t* dst, int32_t dstStart, int32_t count)
+{ uprv_memcpy(dst+dstStart, src+srcStart, (size_t)(count * sizeof(*src))); }
+
+static
+inline void uprv_arrayCopy(const int32_t* src, int32_t* dst, int32_t count)
+{ uprv_memcpy(dst, src, (size_t)(count * sizeof(*src))); }
+
+static
+inline void uprv_arrayCopy(const int32_t* src, int32_t srcStart,
+              int32_t* dst, int32_t dstStart, int32_t count)
+{ uprv_memcpy(dst+dstStart, src+srcStart, (size_t)(count * sizeof(*src))); }
+
+static
+inline void
+uprv_arrayCopy(const UChar *src, int32_t srcStart,
+        UChar *dst, int32_t dstStart, int32_t count)
+{ uprv_memcpy(dst+dstStart, src+srcStart, (size_t)(count * sizeof(*src))); }
+
+/**
+ * Copy an array of UnicodeString OBJECTS (not pointers).
+ * @internal
+ */
+static inline void
+uprv_arrayCopy(const U_NAMESPACE_QUALIFIER UnicodeString *src, U_NAMESPACE_QUALIFIER UnicodeString *dst, int32_t count)
+{ while(count-- > 0) *dst++ = *src++; }
+
+/**
+ * Copy an array of UnicodeString OBJECTS (not pointers).
+ * @internal
+ */
+static inline void
+uprv_arrayCopy(const U_NAMESPACE_QUALIFIER UnicodeString *src, int32_t srcStart,
+        U_NAMESPACE_QUALIFIER UnicodeString *dst, int32_t dstStart, int32_t count)
+{ uprv_arrayCopy(src+srcStart, dst+dstStart, count); }
+
+/**
+ * Checks that the string is readable and writable.
+ * Sets U_ILLEGAL_ARGUMENT_ERROR if the string isBogus() or has an open getBuffer().
+ */
+inline void
+uprv_checkCanGetBuffer(const U_NAMESPACE_QUALIFIER UnicodeString &s, UErrorCode &errorCode) {
+    if(U_SUCCESS(errorCode) && s.isBogus()) {
+        errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+    }
+}
+
+#endif /* _CPPUTILS */
diff --git a/icu/source/common/cstring.c b/icu/source/common/cstring.c
new file mode 100644
index 0000000..a5b2c6b
--- /dev/null
+++ b/icu/source/common/cstring.c
@@ -0,0 +1,328 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1997-2003, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+* File CSTRING.C
+*
+* @author       Helena Shih
+*
+* Modification History:
+*
+*   Date        Name        Description
+*   6/18/98     hshih       Created
+*   09/08/98    stephen     Added include for ctype, for Mac Port
+*   11/15/99    helena      Integrated S/390 IEEE changes. 
+******************************************************************************
+*/
+
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "unicode/utypes.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "uassert.h"
+
+/*
+ * We hardcode case conversion for invariant characters to match our expectation
+ * and the compiler execution charset.
+ * This prevents problems on systems
+ * - with non-default casing behavior, like Turkish system locales where
+ *   tolower('I') maps to dotless i and toupper('i') maps to dotted I
+ * - where there are no lowercase Latin characters at all, or using different
+ *   codes (some old EBCDIC codepages)
+ *
+ * This works because the compiler usually runs on a platform where the execution
+ * charset includes all of the invariant characters at their expected
+ * code positions, so that the char * string literals in ICU code match
+ * the char literals here.
+ *
+ * Note that the set of lowercase Latin letters is discontiguous in EBCDIC
+ * and the set of uppercase Latin letters is discontiguous as well.
+ */
+
+U_CAPI char U_EXPORT2
+uprv_toupper(char c) {
+#if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+    if(('a'<=c && c<='i') || ('j'<=c && c<='r') || ('s'<=c && c<='z')) {
+        c=(char)(c+('A'-'a'));
+    }
+#else
+    if('a'<=c && c<='z') {
+        c=(char)(c+('A'-'a'));
+    }
+#endif
+    return c;
+}
+
+
+#if 0
+/*
+ * Commented out because cstring.h defines uprv_tolower() to be
+ * the same as either uprv_asciitolower() or uprv_ebcdictolower()
+ * to reduce the amount of code to cover with tests.
+ *
+ * Note that this uprv_tolower() definition is likely to work for most
+ * charset families, not just ASCII and EBCDIC, because its #else branch
+ * is written generically.
+ */
+U_CAPI char U_EXPORT2
+uprv_tolower(char c) {
+#if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+    if(('A'<=c && c<='I') || ('J'<=c && c<='R') || ('S'<=c && c<='Z')) {
+        c=(char)(c+('a'-'A'));
+    }
+#else
+    if('A'<=c && c<='Z') {
+        c=(char)(c+('a'-'A'));
+    }
+#endif
+    return c;
+}
+#endif
+
+U_CAPI char U_EXPORT2
+uprv_asciitolower(char c) {
+    if(0x41<=c && c<=0x5a) {
+        c=(char)(c+0x20);
+    }
+    return c;
+}
+
+U_CAPI char U_EXPORT2
+uprv_ebcdictolower(char c) {
+    if( (0xc1<=(uint8_t)c && (uint8_t)c<=0xc9) ||
+        (0xd1<=(uint8_t)c && (uint8_t)c<=0xd9) ||
+        (0xe2<=(uint8_t)c && (uint8_t)c<=0xe9)
+    ) {
+        c=(char)(c-0x40);
+    }
+    return c;
+}
+
+
+U_CAPI char* U_EXPORT2
+T_CString_toLowerCase(char* str)
+{
+    char* origPtr = str;
+
+    if (str) {
+        do
+            *str = (char)uprv_tolower(*str);
+        while (*(str++));
+    }
+
+    return origPtr;
+}
+
+U_CAPI char* U_EXPORT2
+T_CString_toUpperCase(char* str)
+{
+    char* origPtr = str;
+
+    if (str) {
+        do
+            *str = (char)uprv_toupper(*str);
+        while (*(str++));
+    }
+
+    return origPtr;
+}
+
+/*
+ * Takes a int32_t and fills in  a char* string with that number "radix"-based.
+ * Does not handle negative values (makes an empty string for them).
+ * Writes at most 12 chars ("-2147483647" plus NUL).
+ * Returns the length of the string (not including the NUL).
+ */
+U_CAPI int32_t U_EXPORT2
+T_CString_integerToString(char* buffer, int32_t v, int32_t radix)
+{
+    char      tbuf[30];
+    int32_t   tbx    = sizeof(tbuf);
+    uint8_t   digit;
+    int32_t   length = 0;
+    uint32_t  uval;
+    
+    U_ASSERT(radix>=2 && radix<=16);
+    uval = (uint32_t) v;
+    if(v<0 && radix == 10) {
+        /* Only in base 10 do we conside numbers to be signed. */
+        uval = (uint32_t)(-v); 
+        buffer[length++] = '-';
+    }
+    
+    tbx = sizeof(tbuf)-1;
+    tbuf[tbx] = 0;   /* We are generating the digits backwards.  Null term the end. */
+    do {
+        digit = (uint8_t)(uval % radix);
+        tbuf[--tbx] = (char)(T_CString_itosOffset(digit));
+        uval  = uval / radix;
+    } while (uval != 0);
+    
+    /* copy converted number into user buffer  */
+    uprv_strcpy(buffer+length, tbuf+tbx);
+    length += sizeof(tbuf) - tbx -1;
+    return length;
+}
+
+
+
+/*
+ * Takes a int64_t and fills in  a char* string with that number "radix"-based.
+ * Writes at most 21: chars ("-9223372036854775807" plus NUL).
+ * Returns the length of the string, not including the terminating NULL.
+ */
+U_CAPI int32_t U_EXPORT2
+T_CString_int64ToString(char* buffer, int64_t v, uint32_t radix)
+{
+    char      tbuf[30];
+    int32_t   tbx    = sizeof(tbuf);
+    uint8_t   digit;
+    int32_t   length = 0;
+    uint64_t  uval;
+    
+    U_ASSERT(radix>=2 && radix<=16);
+    uval = (uint64_t) v;
+    if(v<0 && radix == 10) {
+        /* Only in base 10 do we conside numbers to be signed. */
+        uval = (uint64_t)(-v); 
+        buffer[length++] = '-';
+    }
+    
+    tbx = sizeof(tbuf)-1;
+    tbuf[tbx] = 0;   /* We are generating the digits backwards.  Null term the end. */
+    do {
+        digit = (uint8_t)(uval % radix);
+        tbuf[--tbx] = (char)(T_CString_itosOffset(digit));
+        uval  = uval / radix;
+    } while (uval != 0);
+    
+    /* copy converted number into user buffer  */
+    uprv_strcpy(buffer+length, tbuf+tbx);
+    length += sizeof(tbuf) - tbx -1;
+    return length;
+}
+
+
+U_CAPI int32_t U_EXPORT2
+T_CString_stringToInteger(const char *integerString, int32_t radix)
+{
+    char *end;
+    return uprv_strtoul(integerString, &end, radix);
+
+}
+    
+U_CAPI int U_EXPORT2
+T_CString_stricmp(const char *str1, const char *str2) {
+    if(str1==NULL) {
+        if(str2==NULL) {
+            return 0;
+        } else {
+            return -1;
+        }
+    } else if(str2==NULL) {
+        return 1;
+    } else {
+        /* compare non-NULL strings lexically with lowercase */
+        int rc;
+        unsigned char c1, c2;
+
+        for(;;) {
+            c1=(unsigned char)*str1;
+            c2=(unsigned char)*str2;
+            if(c1==0) {
+                if(c2==0) {
+                    return 0;
+                } else {
+                    return -1;
+                }
+            } else if(c2==0) {
+                return 1;
+            } else {
+                /* compare non-zero characters with lowercase */
+                rc=(int)(unsigned char)uprv_tolower(c1)-(int)(unsigned char)uprv_tolower(c2);
+                if(rc!=0) {
+                    return rc;
+                }
+            }
+            ++str1;
+            ++str2;
+        }
+    }
+}
+
+U_CAPI int U_EXPORT2
+T_CString_strnicmp(const char *str1, const char *str2, uint32_t n) {
+    if(str1==NULL) {
+        if(str2==NULL) {
+            return 0;
+        } else {
+            return -1;
+        }
+    } else if(str2==NULL) {
+        return 1;
+    } else {
+        /* compare non-NULL strings lexically with lowercase */
+        int rc;
+        unsigned char c1, c2;
+
+        for(; n--;) {
+            c1=(unsigned char)*str1;
+            c2=(unsigned char)*str2;
+            if(c1==0) {
+                if(c2==0) {
+                    return 0;
+                } else {
+                    return -1;
+                }
+            } else if(c2==0) {
+                return 1;
+            } else {
+                /* compare non-zero characters with lowercase */
+                rc=(int)(unsigned char)uprv_tolower(c1)-(int)(unsigned char)uprv_tolower(c2);
+                if(rc!=0) {
+                    return rc;
+                }
+            }
+            ++str1;
+            ++str2;
+        }
+    }
+
+    return 0;
+}
+
+U_CAPI char* U_EXPORT2
+uprv_strdup(const char *src) {
+    size_t len = uprv_strlen(src) + 1;
+    char *dup = (char *) uprv_malloc(len);
+
+    if (dup) {
+        uprv_memcpy(dup, src, len);
+    }
+
+    return dup;
+}
+
+U_CAPI char* U_EXPORT2
+uprv_strndup(const char *src, int32_t n) {
+    char *dup;
+
+    if(n < 0) {
+        dup = uprv_strdup(src);
+    } else {
+        dup = (char*)uprv_malloc(n+1);
+        if (dup) { 
+            uprv_memcpy(dup, src, n);
+            dup[n] = 0;
+        }
+    }
+
+    return dup;
+}
diff --git a/icu/source/common/cstring.h b/icu/source/common/cstring.h
new file mode 100644
index 0000000..6d2fd0e
--- /dev/null
+++ b/icu/source/common/cstring.h
@@ -0,0 +1,120 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1997-2005, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+* File CSTRING.H
+*
+* Contains CString interface
+*
+* @author       Helena Shih
+*
+* Modification History:
+*
+*   Date        Name        Description
+*   6/17/98     hshih       Created.
+*  05/03/99     stephen     Changed from functions to macros.
+*  06/14/99     stephen     Added icu_strncat, icu_strncmp, icu_tolower
+*
+******************************************************************************
+*/
+
+#ifndef CSTRING_H
+#define CSTRING_H 1
+
+#include "unicode/utypes.h"
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#define uprv_strcpy(dst, src) U_STANDARD_CPP_NAMESPACE  strcpy(dst, src)
+#define uprv_strncpy(dst, src, size) U_STANDARD_CPP_NAMESPACE strncpy(dst, src, size)
+#define uprv_strlen(str) U_STANDARD_CPP_NAMESPACE strlen(str)
+#define uprv_strcmp(s1, s2) U_STANDARD_CPP_NAMESPACE strcmp(s1, s2)
+#define uprv_strncmp(s1, s2, n) U_STANDARD_CPP_NAMESPACE strncmp(s1, s2, n)
+#define uprv_strcat(dst, src) U_STANDARD_CPP_NAMESPACE strcat(dst, src)
+#define uprv_strncat(dst, src, n) U_STANDARD_CPP_NAMESPACE strncat(dst, src, n)
+#define uprv_strchr(s, c) U_STANDARD_CPP_NAMESPACE strchr(s, c)
+#define uprv_strstr(s, c) U_STANDARD_CPP_NAMESPACE strstr(s, c)
+#define uprv_strrchr(s, c) U_STANDARD_CPP_NAMESPACE strrchr(s, c)
+
+U_CAPI char U_EXPORT2
+uprv_toupper(char c);
+
+
+U_CAPI char U_EXPORT2
+uprv_asciitolower(char c);
+
+U_CAPI char U_EXPORT2
+uprv_ebcdictolower(char c);
+
+#if U_CHARSET_FAMILY==U_ASCII_FAMILY
+#   define uprv_tolower uprv_asciitolower
+#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+#   define uprv_tolower uprv_ebcdictolower
+#else
+#   error U_CHARSET_FAMILY is not valid
+#endif
+
+#define uprv_strtod(source, end) U_STANDARD_CPP_NAMESPACE strtod(source, end)
+#define uprv_strtoul(str, end, base) U_STANDARD_CPP_NAMESPACE strtoul(str, end, base)
+#define uprv_strtol(str, end, base) U_STANDARD_CPP_NAMESPACE strtol(str, end, base)
+#ifdef U_WINDOWS
+#   if defined(__BORLANDC__)
+#       define uprv_stricmp(str1, str2) U_STANDARD_CPP_NAMESPACE stricmp(str1, str2)
+#       define uprv_strnicmp(str1, str2, n) U_STANDARD_CPP_NAMESPACE strnicmp(str1, str2, n)
+#   else
+#       define uprv_stricmp(str1, str2) U_STANDARD_CPP_NAMESPACE _stricmp(str1, str2)
+#       define uprv_strnicmp(str1, str2, n) U_STANDARD_CPP_NAMESPACE _strnicmp(str1, str2, n)
+#   endif
+#elif defined(POSIX) 
+#   define uprv_stricmp(str1, str2) U_STANDARD_CPP_NAMESPACE strcasecmp(str1, str2) 
+#   define uprv_strnicmp(str1, str2, n) U_STANDARD_CPP_NAMESPACE strncasecmp(str1, str2, n) 
+#else
+#   define uprv_stricmp(str1, str2) T_CString_stricmp(str1, str2)
+#   define uprv_strnicmp(str1, str2, n) T_CString_strnicmp(str1, str2, n)
+#endif
+
+/* Conversion from a digit to the character with radix base from 2-19 */
+/* May need to use U_UPPER_ORDINAL*/
+#define T_CString_itosOffset(a) ((a)<=9?('0'+(a)):('A'+(a)-10))
+
+U_CAPI char* U_EXPORT2
+uprv_strdup(const char *src);
+
+/**
+ * uprv_malloc n+1 bytes, and copy n bytes from src into the new string.
+ * Terminate with a null at offset n.   If n is -1, works like uprv_strdup
+ * @param src
+ * @param n length of the input string, not including null.
+ * @return new string (owned by caller, use uprv_free to free).
+ * @internal
+ */
+U_CAPI char* U_EXPORT2
+uprv_strndup(const char *src, int32_t n);
+
+U_CAPI char* U_EXPORT2
+T_CString_toLowerCase(char* str);
+
+U_CAPI char* U_EXPORT2
+T_CString_toUpperCase(char* str);
+
+U_CAPI int32_t U_EXPORT2
+T_CString_integerToString(char *buffer, int32_t n, int32_t radix);
+
+U_CAPI int32_t U_EXPORT2
+T_CString_int64ToString(char *buffer, int64_t n, uint32_t radix);
+
+U_CAPI int32_t U_EXPORT2
+T_CString_stringToInteger(const char *integerString, int32_t radix);
+
+U_CAPI int U_EXPORT2
+T_CString_stricmp(const char *str1, const char *str2);
+
+U_CAPI int U_EXPORT2
+T_CString_strnicmp(const char *str1, const char *str2, uint32_t n);
+
+#endif /* ! CSTRING_H */
diff --git a/icu/source/common/cwchar.c b/icu/source/common/cwchar.c
new file mode 100644
index 0000000..78bb8c5
--- /dev/null
+++ b/icu/source/common/cwchar.c
@@ -0,0 +1,53 @@
+/*  
+******************************************************************************
+*
+*   Copyright (C) 2001, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*   file name:  cwchar.c
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2001may25
+*   created by: Markus W. Scherer
+*/
+
+#include "unicode/utypes.h"
+
+#if !U_HAVE_WCSCPY
+
+#include "cwchar.h"
+
+U_CAPI wchar_t *uprv_wcscat(wchar_t *dst, const wchar_t *src) {
+    wchar_t *start=dst;
+    while(*dst!=0) {
+        ++dst;
+    }
+    while((*dst=*src)!=0) {
+        ++dst;
+        ++src;
+    }
+    return start;
+}
+
+U_CAPI wchar_t *uprv_wcscpy(wchar_t *dst, const wchar_t *src) {
+    wchar_t *start=dst;
+    while((*dst=*src)!=0) {
+        ++dst;
+        ++src;
+    }
+    return start;
+}
+
+U_CAPI size_t uprv_wcslen(const wchar_t *src) {
+    const wchar_t *start=src;
+    while(*src!=0) {
+        ++src;
+    }
+    return src-start;
+}
+
+#endif
+
diff --git a/icu/source/common/cwchar.h b/icu/source/common/cwchar.h
new file mode 100644
index 0000000..2ab36c0
--- /dev/null
+++ b/icu/source/common/cwchar.h
@@ -0,0 +1,56 @@
+/*  
+******************************************************************************
+*
+*   Copyright (C) 2001, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*   file name:  cwchar.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2001may25
+*   created by: Markus W. Scherer
+*
+*   This file contains ICU-internal definitions of wchar_t operations.
+*   These definitions were moved here from cstring.h so that fewer
+*   ICU implementation files include wchar.h.
+*/
+
+#ifndef __CWCHAR_H__
+#define __CWCHAR_H__
+
+#include <string.h>
+#include <stdlib.h>
+#include "unicode/utypes.h"
+
+/* Do this after utypes.h so that we have U_HAVE_WCHAR_H . */
+#if U_HAVE_WCHAR_H
+#   include <wchar.h>
+#endif
+
+/*===========================================================================*/
+/* Wide-character functions                                                  */
+/*===========================================================================*/
+
+/* The following are not available on all systems, defined in wchar.h or string.h. */
+#if U_HAVE_WCSCPY
+#   define uprv_wcscpy wcscpy
+#   define uprv_wcscat wcscat
+#   define uprv_wcslen wcslen
+#else
+U_CAPI wchar_t* U_EXPORT2 
+uprv_wcscpy(wchar_t *dst, const wchar_t *src);
+U_CAPI wchar_t* U_EXPORT2 
+uprv_wcscat(wchar_t *dst, const wchar_t *src);
+U_CAPI size_t U_EXPORT2 
+uprv_wcslen(const wchar_t *src);
+#endif
+
+/* The following are part of the ANSI C standard, defined in stdlib.h . */
+#define uprv_wcstombs(mbstr, wcstr, count) U_STANDARD_CPP_NAMESPACE wcstombs(mbstr, wcstr, count)
+#define uprv_mbstowcs(wcstr, mbstr, count) U_STANDARD_CPP_NAMESPACE mbstowcs(wcstr, mbstr, count)
+
+
+#endif
diff --git a/icu/source/common/dictbe.cpp b/icu/source/common/dictbe.cpp
new file mode 100644
index 0000000..9698893
--- /dev/null
+++ b/icu/source/common/dictbe.cpp
@@ -0,0 +1,427 @@
+/**
+ *******************************************************************************
+ * Copyright (C) 2006-2008, International Business Machines Corporation and others. *
+ * All Rights Reserved.                                                        *
+ *******************************************************************************
+ */
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "brkeng.h"
+#include "dictbe.h"
+#include "unicode/uniset.h"
+#include "unicode/chariter.h"
+#include "unicode/ubrk.h"
+#include "uvector.h"
+#include "triedict.h"
+
+U_NAMESPACE_BEGIN
+
+/*
+ ******************************************************************
+ */
+
+/*DictionaryBreakEngine::DictionaryBreakEngine() {
+    fTypes = 0;
+}*/
+
+DictionaryBreakEngine::DictionaryBreakEngine(uint32_t breakTypes) {
+    fTypes = breakTypes;
+}
+
+DictionaryBreakEngine::~DictionaryBreakEngine() {
+}
+
+UBool
+DictionaryBreakEngine::handles(UChar32 c, int32_t breakType) const {
+    return (breakType >= 0 && breakType < 32 && (((uint32_t)1 << breakType) & fTypes)
+            && fSet.contains(c));
+}
+
+int32_t
+DictionaryBreakEngine::findBreaks( UText *text,
+                                 int32_t startPos,
+                                 int32_t endPos,
+                                 UBool reverse,
+                                 int32_t breakType,
+                                 UStack &foundBreaks ) const {
+    int32_t result = 0;
+
+    // Find the span of characters included in the set.
+    int32_t start = (int32_t)utext_getNativeIndex(text);
+    int32_t current;
+    int32_t rangeStart;
+    int32_t rangeEnd;
+    UChar32 c = utext_current32(text);
+    if (reverse) {
+        UBool   isDict = fSet.contains(c);
+        while((current = (int32_t)utext_getNativeIndex(text)) > startPos && isDict) {
+            c = utext_previous32(text);
+            isDict = fSet.contains(c);
+        }
+        rangeStart = (current < startPos) ? startPos : current+(isDict ? 0 : 1);
+        rangeEnd = start + 1;
+    }
+    else {
+        while((current = (int32_t)utext_getNativeIndex(text)) < endPos && fSet.contains(c)) {
+            utext_next32(text);         // TODO:  recast loop for postincrement
+            c = utext_current32(text);
+        }
+        rangeStart = start;
+        rangeEnd = current;
+    }
+    if (breakType >= 0 && breakType < 32 && (((uint32_t)1 << breakType) & fTypes)) {
+        result = divideUpDictionaryRange(text, rangeStart, rangeEnd, foundBreaks);
+        utext_setNativeIndex(text, current);
+    }
+    
+    return result;
+}
+
+void
+DictionaryBreakEngine::setCharacters( const UnicodeSet &set ) {
+    fSet = set;
+    // Compact for caching
+    fSet.compact();
+}
+
+/*void
+DictionaryBreakEngine::setBreakTypes( uint32_t breakTypes ) {
+    fTypes = breakTypes;
+}*/
+
+/*
+ ******************************************************************
+ */
+
+
+// Helper class for improving readability of the Thai word break
+// algorithm. The implementation is completely inline.
+
+// List size, limited by the maximum number of words in the dictionary
+// that form a nested sequence.
+#define POSSIBLE_WORD_LIST_MAX 20
+
+class PossibleWord {
+ private:
+  // list of word candidate lengths, in increasing length order
+  int32_t   lengths[POSSIBLE_WORD_LIST_MAX];
+  int       count;      // Count of candidates
+  int32_t   prefix;     // The longest match with a dictionary word
+  int32_t   offset;     // Offset in the text of these candidates
+  int       mark;       // The preferred candidate's offset
+  int       current;    // The candidate we're currently looking at
+
+ public:
+  PossibleWord();
+  ~PossibleWord();
+  
+  // Fill the list of candidates if needed, select the longest, and return the number found
+  int       candidates( UText *text, const TrieWordDictionary *dict, int32_t rangeEnd );
+  
+  // Select the currently marked candidate, point after it in the text, and invalidate self
+  int32_t   acceptMarked( UText *text );
+  
+  // Back up from the current candidate to the next shorter one; return TRUE if that exists
+  // and point the text after it
+  UBool     backUp( UText *text );
+  
+  // Return the longest prefix this candidate location shares with a dictionary word
+  int32_t   longestPrefix();
+  
+  // Mark the current candidate as the one we like
+  void      markCurrent();
+};
+
+inline
+PossibleWord::PossibleWord() {
+    offset = -1;
+}
+
+inline
+PossibleWord::~PossibleWord() {
+}
+
+inline int
+PossibleWord::candidates( UText *text, const TrieWordDictionary *dict, int32_t rangeEnd ) {
+    // TODO: If getIndex is too slow, use offset < 0 and add discardAll()
+    int32_t start = (int32_t)utext_getNativeIndex(text);
+    if (start != offset) {
+        offset = start;
+        prefix = dict->matches(text, rangeEnd-start, lengths, count, sizeof(lengths)/sizeof(lengths[0]));
+        // Dictionary leaves text after longest prefix, not longest word. Back up.
+        if (count <= 0) {
+            utext_setNativeIndex(text, start);
+        }
+    }
+    if (count > 0) {
+        utext_setNativeIndex(text, start+lengths[count-1]);
+    }
+    current = count-1;
+    mark = current;
+    return count;
+}
+
+inline int32_t
+PossibleWord::acceptMarked( UText *text ) {
+    utext_setNativeIndex(text, offset + lengths[mark]);
+    return lengths[mark];
+}
+
+inline UBool
+PossibleWord::backUp( UText *text ) {
+    if (current > 0) {
+        utext_setNativeIndex(text, offset + lengths[--current]);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+inline int32_t
+PossibleWord::longestPrefix() {
+    return prefix;
+}
+
+inline void
+PossibleWord::markCurrent() {
+    mark = current;
+}
+
+// How many words in a row are "good enough"?
+#define THAI_LOOKAHEAD 3
+
+// Will not combine a non-word with a preceding dictionary word longer than this
+#define THAI_ROOT_COMBINE_THRESHOLD 3
+
+// Will not combine a non-word that shares at least this much prefix with a
+// dictionary word, with a preceding word
+#define THAI_PREFIX_COMBINE_THRESHOLD 3
+
+// Ellision character
+#define THAI_PAIYANNOI 0x0E2F
+
+// Repeat character
+#define THAI_MAIYAMOK 0x0E46
+
+// Minimum word size
+#define THAI_MIN_WORD 2
+
+// Minimum number of characters for two words
+#define THAI_MIN_WORD_SPAN (THAI_MIN_WORD * 2)
+
+ThaiBreakEngine::ThaiBreakEngine(const TrieWordDictionary *adoptDictionary, UErrorCode &status)
+    : DictionaryBreakEngine((1<<UBRK_WORD) | (1<<UBRK_LINE)),
+      fDictionary(adoptDictionary)
+{
+    fThaiWordSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Thai:]&[:LineBreak=SA:]]"), status);
+    if (U_SUCCESS(status)) {
+        setCharacters(fThaiWordSet);
+    }
+    fMarkSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Thai:]&[:LineBreak=SA:]&[:M:]]"), status);
+    fMarkSet.add(0x0020);
+    fEndWordSet = fThaiWordSet;
+    fEndWordSet.remove(0x0E31);             // MAI HAN-AKAT
+    fEndWordSet.remove(0x0E40, 0x0E44);     // SARA E through SARA AI MAIMALAI
+    fBeginWordSet.add(0x0E01, 0x0E2E);      // KO KAI through HO NOKHUK
+    fBeginWordSet.add(0x0E40, 0x0E44);      // SARA E through SARA AI MAIMALAI
+    fSuffixSet.add(THAI_PAIYANNOI);
+    fSuffixSet.add(THAI_MAIYAMOK);
+
+    // Compact for caching.
+    fMarkSet.compact();
+    fEndWordSet.compact();
+    fBeginWordSet.compact();
+    fSuffixSet.compact();
+}
+
+ThaiBreakEngine::~ThaiBreakEngine() {
+    delete fDictionary;
+}
+
+int32_t
+ThaiBreakEngine::divideUpDictionaryRange( UText *text,
+                                                int32_t rangeStart,
+                                                int32_t rangeEnd,
+                                                UStack &foundBreaks ) const {
+    if ((rangeEnd - rangeStart) < THAI_MIN_WORD_SPAN) {
+        return 0;       // Not enough characters for two words
+    }
+
+    uint32_t wordsFound = 0;
+    int32_t wordLength;
+    int32_t current;
+    UErrorCode status = U_ZERO_ERROR;
+    PossibleWord words[THAI_LOOKAHEAD];
+    UChar32 uc;
+    
+    utext_setNativeIndex(text, rangeStart);
+    
+    while (U_SUCCESS(status) && (current = (int32_t)utext_getNativeIndex(text)) < rangeEnd) {
+        wordLength = 0;
+
+        // Look for candidate words at the current position
+        int candidates = words[wordsFound%THAI_LOOKAHEAD].candidates(text, fDictionary, rangeEnd);
+        
+        // If we found exactly one, use that
+        if (candidates == 1) {
+            wordLength = words[wordsFound%THAI_LOOKAHEAD].acceptMarked(text);
+            wordsFound += 1;
+        }
+        
+        // If there was more than one, see which one can take us forward the most words
+        else if (candidates > 1) {
+            // If we're already at the end of the range, we're done
+            if ((int32_t)utext_getNativeIndex(text) >= rangeEnd) {
+                goto foundBest;
+            }
+            do {
+                int wordsMatched = 1;
+                if (words[(wordsFound+1)%THAI_LOOKAHEAD].candidates(text, fDictionary, rangeEnd) > 0) {
+                    if (wordsMatched < 2) {
+                        // Followed by another dictionary word; mark first word as a good candidate
+                        words[wordsFound%THAI_LOOKAHEAD].markCurrent();
+                        wordsMatched = 2;
+                    }
+                    
+                    // If we're already at the end of the range, we're done
+                    if ((int32_t)utext_getNativeIndex(text) >= rangeEnd) {
+                        goto foundBest;
+                    }
+                    
+                    // See if any of the possible second words is followed by a third word
+                    do {
+                        // If we find a third word, stop right away
+                        if (words[(wordsFound+2)%THAI_LOOKAHEAD].candidates(text, fDictionary, rangeEnd)) {
+                            words[wordsFound%THAI_LOOKAHEAD].markCurrent();
+                            goto foundBest;
+                        }
+                    }
+                    while (words[(wordsFound+1)%THAI_LOOKAHEAD].backUp(text));
+                }
+            }
+            while (words[wordsFound%THAI_LOOKAHEAD].backUp(text));
+foundBest:
+            wordLength = words[wordsFound%THAI_LOOKAHEAD].acceptMarked(text);
+            wordsFound += 1;
+        }
+        
+        // We come here after having either found a word or not. We look ahead to the
+        // next word. If it's not a dictionary word, we will combine it withe the word we
+        // just found (if there is one), but only if the preceding word does not exceed
+        // the threshold.
+        // The text iterator should now be positioned at the end of the word we found.
+        if ((int32_t)utext_getNativeIndex(text) < rangeEnd && wordLength < THAI_ROOT_COMBINE_THRESHOLD) {
+            // if it is a dictionary word, do nothing. If it isn't, then if there is
+            // no preceding word, or the non-word shares less than the minimum threshold
+            // of characters with a dictionary word, then scan to resynchronize
+            if (words[wordsFound%THAI_LOOKAHEAD].candidates(text, fDictionary, rangeEnd) <= 0
+                  && (wordLength == 0
+                      || words[wordsFound%THAI_LOOKAHEAD].longestPrefix() < THAI_PREFIX_COMBINE_THRESHOLD)) {
+                // Look for a plausible word boundary
+                //TODO: This section will need a rework for UText.
+                int32_t remaining = rangeEnd - (current+wordLength);
+                UChar32 pc = utext_current32(text);
+                int32_t chars = 0;
+                for (;;) {
+                    utext_next32(text);
+                    uc = utext_current32(text);
+                    // TODO: Here we're counting on the fact that the SA languages are all
+                    // in the BMP. This should get fixed with the UText rework.
+                    chars += 1;
+                    if (--remaining <= 0) {
+                        break;
+                    }
+                    if (fEndWordSet.contains(pc) && fBeginWordSet.contains(uc)) {
+                        // Maybe. See if it's in the dictionary.
+                        // NOTE: In the original Apple code, checked that the next
+                        // two characters after uc were not 0x0E4C THANTHAKHAT before
+                        // checking the dictionary. That is just a performance filter,
+                        // but it's not clear it's faster than checking the trie.
+                        int candidates = words[(wordsFound+1)%THAI_LOOKAHEAD].candidates(text, fDictionary, rangeEnd);
+                        utext_setNativeIndex(text, current+wordLength+chars);
+                        if (candidates > 0) {
+                            break;
+                        }
+                    }
+                    pc = uc;
+                }
+                
+                // Bump the word count if there wasn't already one
+                if (wordLength <= 0) {
+                    wordsFound += 1;
+                }
+                
+                // Update the length with the passed-over characters
+                wordLength += chars;
+            }
+            else {
+                // Back up to where we were for next iteration
+                utext_setNativeIndex(text, current+wordLength);
+            }
+        }
+        
+        // Never stop before a combining mark.
+        int32_t currPos;
+        while ((currPos = (int32_t)utext_getNativeIndex(text)) < rangeEnd && fMarkSet.contains(utext_current32(text))) {
+            utext_next32(text);
+            wordLength += (int32_t)utext_getNativeIndex(text) - currPos;
+        }
+        
+        // Look ahead for possible suffixes if a dictionary word does not follow.
+        // We do this in code rather than using a rule so that the heuristic
+        // resynch continues to function. For example, one of the suffix characters
+        // could be a typo in the middle of a word.
+        if ((int32_t)utext_getNativeIndex(text) < rangeEnd && wordLength > 0) {
+            if (words[wordsFound%THAI_LOOKAHEAD].candidates(text, fDictionary, rangeEnd) <= 0
+                && fSuffixSet.contains(uc = utext_current32(text))) {
+                if (uc == THAI_PAIYANNOI) {
+                    if (!fSuffixSet.contains(utext_previous32(text))) {
+                        // Skip over previous end and PAIYANNOI
+                        utext_next32(text);
+                        utext_next32(text);
+                        wordLength += 1;            // Add PAIYANNOI to word
+                        uc = utext_current32(text);     // Fetch next character
+                    }
+                    else {
+                        // Restore prior position
+                        utext_next32(text);
+                    }
+                }
+                if (uc == THAI_MAIYAMOK) {
+                    if (utext_previous32(text) != THAI_MAIYAMOK) {
+                        // Skip over previous end and MAIYAMOK
+                        utext_next32(text);
+                        utext_next32(text);
+                        wordLength += 1;            // Add MAIYAMOK to word
+                    }
+                    else {
+                        // Restore prior position
+                        utext_next32(text);
+                    }
+                }
+            }
+            else {
+                utext_setNativeIndex(text, current+wordLength);
+            }
+        }
+        
+        // Did we find a word on this iteration? If so, push it on the break stack
+        if (wordLength > 0) {
+            foundBreaks.push((current+wordLength), status);
+        }
+    }
+    
+    // Don't return a break for the end of the dictionary range if there is one there.
+    if (foundBreaks.peeki() >= rangeEnd) {
+        (void) foundBreaks.popi();
+        wordsFound -= 1;
+    }
+
+    return wordsFound;
+}
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/icu/source/common/dictbe.h b/icu/source/common/dictbe.h
new file mode 100644
index 0000000..d6f8b14
--- /dev/null
+++ b/icu/source/common/dictbe.h
@@ -0,0 +1,193 @@
+/**
+ *******************************************************************************
+ * Copyright (C) 2006, International Business Machines Corporation and others. *
+ * All Rights Reserved.                                                        *
+ *******************************************************************************
+ */
+
+#ifndef DICTBE_H
+#define DICTBE_H
+
+#include "unicode/utypes.h"
+#include "unicode/uniset.h"
+#include "unicode/utext.h"
+
+#include "brkeng.h"
+
+U_NAMESPACE_BEGIN
+
+class TrieWordDictionary;
+
+/*******************************************************************
+ * DictionaryBreakEngine
+ */
+
+/**
+ * <p>DictionaryBreakEngine is a kind of LanguageBreakEngine that uses a
+ * dictionary to determine language-specific breaks.</p>
+ *
+ * <p>After it is constructed a DictionaryBreakEngine may be shared between
+ * threads without synchronization.</p>
+ */
+class DictionaryBreakEngine : public LanguageBreakEngine {
+ private:
+    /**
+     * The set of characters handled by this engine
+     * @internal
+     */
+
+  UnicodeSet    fSet;
+
+    /**
+     * The set of break types handled by this engine
+     * @internal
+     */
+
+  uint32_t      fTypes;
+
+  /**
+   * <p>Default constructor.</p>
+   *
+   */
+  DictionaryBreakEngine();
+
+ public:
+
+  /**
+   * <p>Constructor setting the break types handled.</p>
+   *
+   * @param breakTypes A bitmap of types handled by the engine.
+   */
+  DictionaryBreakEngine( uint32_t breakTypes );
+
+  /**
+   * <p>Virtual destructor.</p>
+   */
+  virtual ~DictionaryBreakEngine();
+
+ /**
+  * <p>Indicate whether this engine handles a particular character for
+  * a particular kind of break.</p>
+  *
+  * @param c A character which begins a run that the engine might handle
+  * @param breakType The type of text break which the caller wants to determine
+  * @return TRUE if this engine handles the particular character and break
+  * type.
+  */
+  virtual UBool handles( UChar32 c, int32_t breakType ) const;
+
+ /**
+  * <p>Find any breaks within a run in the supplied text.</p>
+  *
+  * @param text A UText representing the text. The
+  * iterator is left at the end of the run of characters which the engine
+  * is capable of handling.
+  * @param startPos The start of the run within the supplied text.
+  * @param endPos The end of the run within the supplied text.
+  * @param reverse Whether the caller is looking for breaks in a reverse
+  * direction.
+  * @param breakType The type of break desired, or -1.
+  * @param foundBreaks An allocated C array of the breaks found, if any
+  * @return The number of breaks found.
+  */
+  virtual int32_t findBreaks( UText *text,
+                              int32_t startPos,
+                              int32_t endPos,
+                              UBool reverse,
+                              int32_t breakType,
+                              UStack &foundBreaks ) const;
+
+ protected:
+
+ /**
+  * <p>Set the character set handled by this engine.</p>
+  *
+  * @param set A UnicodeSet of the set of characters handled by the engine
+  */
+  virtual void setCharacters( const UnicodeSet &set );
+
+ /**
+  * <p>Set the break types handled by this engine.</p>
+  *
+  * @param breakTypes A bitmap of types handled by the engine.
+  */
+//  virtual void setBreakTypes( uint32_t breakTypes );
+
+ /**
+  * <p>Divide up a range of known dictionary characters.</p>
+  *
+  * @param text A UText representing the text
+  * @param rangeStart The start of the range of dictionary characters
+  * @param rangeEnd The end of the range of dictionary characters
+  * @param foundBreaks Output of C array of int32_t break positions, or 0
+  * @return The number of breaks found
+  */
+  virtual int32_t divideUpDictionaryRange( UText *text,
+                                           int32_t rangeStart,
+                                           int32_t rangeEnd,
+                                           UStack &foundBreaks ) const = 0;
+
+};
+
+/*******************************************************************
+ * ThaiBreakEngine
+ */
+
+/**
+ * <p>ThaiBreakEngine is a kind of DictionaryBreakEngine that uses a
+ * TrieWordDictionary and heuristics to determine Thai-specific breaks.</p>
+ *
+ * <p>After it is constructed a ThaiBreakEngine may be shared between
+ * threads without synchronization.</p>
+ */
+class ThaiBreakEngine : public DictionaryBreakEngine {
+ private:
+    /**
+     * The set of characters handled by this engine
+     * @internal
+     */
+
+  UnicodeSet                fThaiWordSet;
+  UnicodeSet                fEndWordSet;
+  UnicodeSet                fBeginWordSet;
+  UnicodeSet                fSuffixSet;
+  UnicodeSet                fMarkSet;
+  const TrieWordDictionary  *fDictionary;
+
+ public:
+
+  /**
+   * <p>Default constructor.</p>
+   *
+   * @param adoptDictionary A TrieWordDictionary to adopt. Deleted when the
+   * engine is deleted.
+   */
+  ThaiBreakEngine(const TrieWordDictionary *adoptDictionary, UErrorCode &status);
+
+  /**
+   * <p>Virtual destructor.</p>
+   */
+  virtual ~ThaiBreakEngine();
+
+ protected:
+ /**
+  * <p>Divide up a range of known dictionary characters.</p>
+  *
+  * @param text A UText representing the text
+  * @param rangeStart The start of the range of dictionary characters
+  * @param rangeEnd The end of the range of dictionary characters
+  * @param foundBreaks Output of C array of int32_t break positions, or 0
+  * @return The number of breaks found
+  */
+  virtual int32_t divideUpDictionaryRange( UText *text,
+                                           int32_t rangeStart,
+                                           int32_t rangeEnd,
+                                           UStack &foundBreaks ) const;
+
+};
+
+
+U_NAMESPACE_END
+
+    /* DICTBE_H */
+#endif
diff --git a/icu/source/common/dtintrv.cpp b/icu/source/common/dtintrv.cpp
new file mode 100644
index 0000000..bece836
--- /dev/null
+++ b/icu/source/common/dtintrv.cpp
@@ -0,0 +1,61 @@
+/*******************************************************************************
+* Copyright (C) 2008, International Business Machines Corporation and
+* others. All Rights Reserved.
+*******************************************************************************
+*
+* File DTINTRV.CPP 
+*
+*******************************************************************************
+*/
+
+
+
+#include "unicode/dtintrv.h"
+
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateInterval)
+
+//DateInterval::DateInterval(){}
+
+
+DateInterval::DateInterval(UDate from, UDate to)
+:   fromDate(from),
+    toDate(to)
+{}
+
+
+DateInterval::~DateInterval(){}
+
+
+DateInterval::DateInterval(const DateInterval& other)
+: UObject(other) {
+    *this = other;
+}   
+
+
+DateInterval&
+DateInterval::operator=(const DateInterval& other) {
+    if ( this != &other ) {
+        fromDate = other.fromDate;
+        toDate = other.toDate;
+    }
+    return *this;
+}
+
+
+DateInterval* 
+DateInterval::clone() const {
+    return new DateInterval(*this);
+}
+
+
+UBool 
+DateInterval::operator==(const DateInterval& other) const { 
+    return ( fromDate == other.fromDate && toDate == other.toDate );
+}
+
+
+U_NAMESPACE_END
+
diff --git a/icu/source/common/errorcode.cpp b/icu/source/common/errorcode.cpp
new file mode 100644
index 0000000..4ff151e
--- /dev/null
+++ b/icu/source/common/errorcode.cpp
@@ -0,0 +1,38 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2009, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  errorcode.cpp
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2009mar10
+*   created by: Markus W. Scherer
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/errorcode.h"
+
+U_NAMESPACE_BEGIN
+
+UErrorCode ErrorCode::reset() {
+    UErrorCode code = errorCode;
+    errorCode = U_ZERO_ERROR;
+    return code;
+}
+
+void ErrorCode::assertSuccess() const {
+    if(isFailure()) {
+        handleFailure();
+    }
+}
+
+const char* ErrorCode::errorName() const {
+  return u_errorName(errorCode);
+}
+
+U_NAMESPACE_END
diff --git a/icu/source/common/filterednormalizer2.cpp b/icu/source/common/filterednormalizer2.cpp
new file mode 100644
index 0000000..c124a46
--- /dev/null
+++ b/icu/source/common/filterednormalizer2.cpp
@@ -0,0 +1,268 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2009-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  filterednormalizer2.cpp
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2009dec10
+*   created by: Markus W. Scherer
+*/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_NORMALIZATION
+
+#include "unicode/normalizer2.h"
+#include "unicode/uniset.h"
+#include "unicode/unistr.h"
+#include "unicode/unorm.h"
+#include "cpputils.h"
+
+U_NAMESPACE_BEGIN
+
+UnicodeString &
+FilteredNormalizer2::normalize(const UnicodeString &src,
+                               UnicodeString &dest,
+                               UErrorCode &errorCode) const {
+    uprv_checkCanGetBuffer(src, errorCode);
+    if(U_FAILURE(errorCode)) {
+        dest.setToBogus();
+        return dest;
+    }
+    if(&dest==&src) {
+        errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return dest;
+    }
+    dest.remove();
+    return normalize(src, dest, USET_SPAN_SIMPLE, errorCode);
+}
+
+// Internal: No argument checking, and appends to dest.
+// Pass as input spanCondition the one that is likely to yield a non-zero
+// span length at the start of src.
+// For set=[:age=3.2:], since almost all common characters were in Unicode 3.2,
+// USET_SPAN_SIMPLE should be passed in for the start of src
+// and USET_SPAN_NOT_CONTAINED should be passed in if we continue after
+// an in-filter prefix.
+UnicodeString &
+FilteredNormalizer2::normalize(const UnicodeString &src,
+                               UnicodeString &dest,
+                               USetSpanCondition spanCondition,
+                               UErrorCode &errorCode) const {
+    UnicodeString tempDest;  // Don't throw away destination buffer between iterations.
+    for(int32_t prevSpanLimit=0; prevSpanLimit<src.length();) {
+        int32_t spanLimit=set.span(src, prevSpanLimit, spanCondition);
+        int32_t spanLength=spanLimit-prevSpanLimit;
+        if(spanCondition==USET_SPAN_NOT_CONTAINED) {
+            if(spanLength!=0) {
+                dest.append(src, prevSpanLimit, spanLength);
+            }
+            spanCondition=USET_SPAN_SIMPLE;
+        } else {
+            if(spanLength!=0) {
+                // Not norm2.normalizeSecondAndAppend() because we do not want
+                // to modify the non-filter part of dest.
+                dest.append(norm2.normalize(src.tempSubStringBetween(prevSpanLimit, spanLimit),
+                                            tempDest, errorCode));
+                if(U_FAILURE(errorCode)) {
+                    break;
+                }
+            }
+            spanCondition=USET_SPAN_NOT_CONTAINED;
+        }
+        prevSpanLimit=spanLimit;
+    }
+    return dest;
+}
+
+UnicodeString &
+FilteredNormalizer2::normalizeSecondAndAppend(UnicodeString &first,
+                                              const UnicodeString &second,
+                                              UErrorCode &errorCode) const {
+    return normalizeSecondAndAppend(first, second, TRUE, errorCode);
+}
+
+UnicodeString &
+FilteredNormalizer2::append(UnicodeString &first,
+                            const UnicodeString &second,
+                            UErrorCode &errorCode) const {
+    return normalizeSecondAndAppend(first, second, FALSE, errorCode);
+}
+
+UnicodeString &
+FilteredNormalizer2::normalizeSecondAndAppend(UnicodeString &first,
+                                              const UnicodeString &second,
+                                              UBool doNormalize,
+                                              UErrorCode &errorCode) const {
+    uprv_checkCanGetBuffer(first, errorCode);
+    uprv_checkCanGetBuffer(second, errorCode);
+    if(U_FAILURE(errorCode)) {
+        return first;
+    }
+    if(&first==&second) {
+        errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return first;
+    }
+    if(first.isEmpty()) {
+        if(doNormalize) {
+            return normalize(second, first, errorCode);
+        } else {
+            return first=second;
+        }
+    }
+    // merge the in-filter suffix of the first string with the in-filter prefix of the second
+    int32_t prefixLimit=set.span(second, 0, USET_SPAN_SIMPLE);
+    if(prefixLimit!=0) {
+        UnicodeString prefix(second.tempSubString(0, prefixLimit));
+        int32_t suffixStart=set.spanBack(first, INT32_MAX, USET_SPAN_SIMPLE);
+        if(suffixStart==0) {
+            if(doNormalize) {
+                norm2.normalizeSecondAndAppend(first, prefix, errorCode);
+            } else {
+                norm2.append(first, prefix, errorCode);
+            }
+        } else {
+            UnicodeString middle(first, suffixStart, INT32_MAX);
+            if(doNormalize) {
+                norm2.normalizeSecondAndAppend(middle, prefix, errorCode);
+            } else {
+                norm2.append(middle, prefix, errorCode);
+            }
+            first.replace(suffixStart, INT32_MAX, middle);
+        }
+    }
+    if(prefixLimit<second.length()) {
+        UnicodeString rest(second.tempSubString(prefixLimit, INT32_MAX));
+        if(doNormalize) {
+            normalize(rest, first, USET_SPAN_NOT_CONTAINED, errorCode);
+        } else {
+            first.append(rest);
+        }
+    }
+    return first;
+}
+
+UBool
+FilteredNormalizer2::isNormalized(const UnicodeString &s, UErrorCode &errorCode) const {
+    uprv_checkCanGetBuffer(s, errorCode);
+    if(U_FAILURE(errorCode)) {
+        return FALSE;
+    }
+    USetSpanCondition spanCondition=USET_SPAN_SIMPLE;
+    for(int32_t prevSpanLimit=0; prevSpanLimit<s.length();) {
+        int32_t spanLimit=set.span(s, prevSpanLimit, spanCondition);
+        if(spanCondition==USET_SPAN_NOT_CONTAINED) {
+            spanCondition=USET_SPAN_SIMPLE;
+        } else {
+            if( !norm2.isNormalized(s.tempSubStringBetween(prevSpanLimit, spanLimit), errorCode) ||
+                U_FAILURE(errorCode)
+            ) {
+                return FALSE;
+            }
+            spanCondition=USET_SPAN_NOT_CONTAINED;
+        }
+        prevSpanLimit=spanLimit;
+    }
+    return TRUE;
+}
+
+UNormalizationCheckResult
+FilteredNormalizer2::quickCheck(const UnicodeString &s, UErrorCode &errorCode) const {
+    uprv_checkCanGetBuffer(s, errorCode);
+    if(U_FAILURE(errorCode)) {
+        return UNORM_MAYBE;
+    }
+    UNormalizationCheckResult result=UNORM_YES;
+    USetSpanCondition spanCondition=USET_SPAN_SIMPLE;
+    for(int32_t prevSpanLimit=0; prevSpanLimit<s.length();) {
+        int32_t spanLimit=set.span(s, prevSpanLimit, spanCondition);
+        if(spanCondition==USET_SPAN_NOT_CONTAINED) {
+            spanCondition=USET_SPAN_SIMPLE;
+        } else {
+            UNormalizationCheckResult qcResult=
+                norm2.quickCheck(s.tempSubStringBetween(prevSpanLimit, spanLimit), errorCode);
+            if(U_FAILURE(errorCode) || qcResult==UNORM_NO) {
+                return qcResult;
+            } else if(qcResult==UNORM_MAYBE) {
+                result=qcResult;
+            }
+            spanCondition=USET_SPAN_NOT_CONTAINED;
+        }
+        prevSpanLimit=spanLimit;
+    }
+    return result;
+}
+
+int32_t
+FilteredNormalizer2::spanQuickCheckYes(const UnicodeString &s, UErrorCode &errorCode) const {
+    uprv_checkCanGetBuffer(s, errorCode);
+    if(U_FAILURE(errorCode)) {
+        return 0;
+    }
+    USetSpanCondition spanCondition=USET_SPAN_SIMPLE;
+    for(int32_t prevSpanLimit=0; prevSpanLimit<s.length();) {
+        int32_t spanLimit=set.span(s, prevSpanLimit, spanCondition);
+        if(spanCondition==USET_SPAN_NOT_CONTAINED) {
+            spanCondition=USET_SPAN_SIMPLE;
+        } else {
+            int32_t yesLimit=
+                prevSpanLimit+
+                norm2.spanQuickCheckYes(
+                    s.tempSubStringBetween(prevSpanLimit, spanLimit), errorCode);
+            if(U_FAILURE(errorCode) || yesLimit<spanLimit) {
+                return yesLimit;
+            }
+            spanCondition=USET_SPAN_NOT_CONTAINED;
+        }
+        prevSpanLimit=spanLimit;
+    }
+    return s.length();
+}
+
+UBool
+FilteredNormalizer2::hasBoundaryBefore(UChar32 c) const {
+    return !set.contains(c) || norm2.hasBoundaryBefore(c);
+}
+
+UBool
+FilteredNormalizer2::hasBoundaryAfter(UChar32 c) const {
+    return !set.contains(c) || norm2.hasBoundaryAfter(c);
+}
+
+UBool
+FilteredNormalizer2::isInert(UChar32 c) const {
+    return !set.contains(c) || norm2.isInert(c);
+}
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(FilteredNormalizer2)
+
+U_NAMESPACE_END
+
+// C API ------------------------------------------------------------------- ***
+
+U_NAMESPACE_USE
+
+U_DRAFT UNormalizer2 * U_EXPORT2
+unorm2_openFiltered(const UNormalizer2 *norm2, const USet *filterSet, UErrorCode *pErrorCode) {
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+    if(filterSet==NULL) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return NULL;
+    }
+    Normalizer2 *fn2=new FilteredNormalizer2(*(Normalizer2 *)norm2,
+                                             *UnicodeSet::fromUSet(filterSet));
+    if(fn2==NULL) {
+        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+    }
+    return (UNormalizer2 *)fn2;
+}
+
+#endif  // !UCONFIG_NO_NORMALIZATION
diff --git a/icu/source/common/hash.h b/icu/source/common/hash.h
new file mode 100644
index 0000000..9fedd0e
--- /dev/null
+++ b/icu/source/common/hash.h
@@ -0,0 +1,207 @@
+/*
+******************************************************************************
+*   Copyright (C) 1997-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+******************************************************************************
+*   Date        Name        Description
+*   03/28/00    aliu        Creation.
+******************************************************************************
+*/
+
+#ifndef HASH_H
+#define HASH_H
+
+#include "unicode/unistr.h"
+#include "unicode/uobject.h"
+#include "uhash.h"
+
+U_NAMESPACE_BEGIN
+
+/**
+ * Hashtable is a thin C++ wrapper around UHashtable, a general-purpose void*
+ * hashtable implemented in C.  Hashtable is designed to be idiomatic and
+ * easy-to-use in C++.
+ *
+ * Hashtable is an INTERNAL CLASS.
+ */
+class U_COMMON_API Hashtable : public UMemory {
+    UHashtable* hash;
+    UHashtable hashObj;
+
+    inline void init(UHashFunction *keyHash, UKeyComparator *keyComp, UValueComparator *valueComp, UErrorCode& status);
+
+public:
+    /**
+     * Construct a hashtable
+     * @param ignoreKeyCase If true, keys are case insensitive.
+     * @param status Error code
+    */
+    Hashtable(UBool ignoreKeyCase, UErrorCode& status);
+
+    /**
+     * Construct a hashtable
+     * @param keyComp Comparator for comparing the keys
+     * @param valueComp Comparator for comparing the values
+     * @param status Error code
+    */
+    Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp, UErrorCode& status);
+
+    /**
+     * Construct a hashtable
+     * @param status Error code
+    */
+    Hashtable(UErrorCode& status);
+
+    /**
+     * Construct a hashtable, _disregarding any error_.  Use this constructor
+     * with caution.
+     */
+    Hashtable();
+
+    /**
+     * Non-virtual destructor; make this virtual if Hashtable is subclassed
+     * in the future.
+     */
+    ~Hashtable();
+
+    UObjectDeleter *setValueDeleter(UObjectDeleter *fn);
+
+    int32_t count() const;
+
+    void* put(const UnicodeString& key, void* value, UErrorCode& status);
+
+    int32_t puti(const UnicodeString& key, int32_t value, UErrorCode& status);
+
+    void* get(const UnicodeString& key) const;
+    
+    int32_t geti(const UnicodeString& key) const;
+    
+    void* remove(const UnicodeString& key);
+
+    int32_t removei(const UnicodeString& key);
+
+    void removeAll(void);
+
+    const UHashElement* find(const UnicodeString& key) const;
+
+    const UHashElement* nextElement(int32_t& pos) const;
+    
+    UKeyComparator* setKeyComparator(UKeyComparator*keyComp);
+    
+    UValueComparator* setValueComparator(UValueComparator* valueComp);
+
+    UBool equals(const Hashtable& that) const;
+private:
+    Hashtable(const Hashtable &other); // forbid copying of this class
+    Hashtable &operator=(const Hashtable &other); // forbid copying of this class
+};
+
+/*********************************************************************
+ * Implementation
+ ********************************************************************/
+
+inline void Hashtable::init(UHashFunction *keyHash, UKeyComparator *keyComp, 
+                            UValueComparator *valueComp, UErrorCode& status) {
+    if (U_FAILURE(status)) {
+        return;
+    }
+    uhash_init(&hashObj, keyHash, keyComp, valueComp, &status);
+    if (U_SUCCESS(status)) {
+        hash = &hashObj;
+        uhash_setKeyDeleter(hash, uhash_deleteUnicodeString);
+    }
+}
+
+inline Hashtable::Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp, 
+                 UErrorCode& status) : hash(0) {
+    init( uhash_hashUnicodeString, keyComp, valueComp, status);
+}
+inline Hashtable::Hashtable(UBool ignoreKeyCase, UErrorCode& status)
+ : hash(0)
+{
+    init(ignoreKeyCase ? uhash_hashCaselessUnicodeString
+                        : uhash_hashUnicodeString,
+            ignoreKeyCase ? uhash_compareCaselessUnicodeString
+                        : uhash_compareUnicodeString,
+            NULL,
+            status);
+}
+
+inline Hashtable::Hashtable(UErrorCode& status)
+ : hash(0)
+{
+    init(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, status);
+}
+
+inline Hashtable::Hashtable()
+ : hash(0)
+{
+    UErrorCode status = U_ZERO_ERROR;
+    init(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, status);
+}
+
+inline Hashtable::~Hashtable() {
+    if (hash != NULL) {
+        uhash_close(hash);
+    }
+}
+
+inline UObjectDeleter *Hashtable::setValueDeleter(UObjectDeleter *fn) {
+    return uhash_setValueDeleter(hash, fn);
+}
+
+inline int32_t Hashtable::count() const {
+    return uhash_count(hash);
+}
+
+inline void* Hashtable::put(const UnicodeString& key, void* value, UErrorCode& status) {
+    return uhash_put(hash, new UnicodeString(key), value, &status);
+}
+
+inline int32_t Hashtable::puti(const UnicodeString& key, int32_t value, UErrorCode& status) {
+    return uhash_puti(hash, new UnicodeString(key), value, &status);
+}
+
+inline void* Hashtable::get(const UnicodeString& key) const {
+    return uhash_get(hash, &key);
+}
+
+inline int32_t Hashtable::geti(const UnicodeString& key) const {
+    return uhash_geti(hash, &key);
+}
+
+inline void* Hashtable::remove(const UnicodeString& key) {
+    return uhash_remove(hash, &key);
+}
+
+inline int32_t Hashtable::removei(const UnicodeString& key) {
+    return uhash_removei(hash, &key);
+}
+
+inline const UHashElement* Hashtable::find(const UnicodeString& key) const {
+    return uhash_find(hash, &key);
+}
+
+inline const UHashElement* Hashtable::nextElement(int32_t& pos) const {
+    return uhash_nextElement(hash, &pos);
+}
+
+inline void Hashtable::removeAll(void) {
+    uhash_removeAll(hash);
+}
+
+inline UKeyComparator* Hashtable::setKeyComparator(UKeyComparator*keyComp){
+    return uhash_setKeyComparator(hash, keyComp);
+}
+    
+inline UValueComparator* Hashtable::setValueComparator(UValueComparator* valueComp){
+    return uhash_setValueComparator(hash, valueComp);
+}
+
+inline UBool Hashtable::equals(const Hashtable& that)const{
+   return uhash_equals(hash, that.hash);
+}
+U_NAMESPACE_END
+
+#endif
+
diff --git a/icu/source/common/icucfg.h.in b/icu/source/common/icucfg.h.in
new file mode 100644
index 0000000..c3fe6b5
--- /dev/null
+++ b/icu/source/common/icucfg.h.in
@@ -0,0 +1,112 @@
+/* common/icucfg.h.in.  Generated from configure.in by autoheader.  */
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Define to 1 if you have the <dirent.h> header file. */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the `dlopen' function. */
+#undef HAVE_DLOPEN
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#undef HAVE_LIBPTHREAD
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* wchar.h was found. */
+#undef HAVE_WCHAR_H
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* The size of `void *', as computed by sizeof. */
+#undef SIZEOF_VOID_P
+
+/* The size of `wchar_t', as computed by sizeof. */
+#undef SIZEOF_WCHAR_T
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+#  undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define to `signed short' if <sys/types.h> does not define. */
+#undef int16_t
+
+/* Define to `signed long' if <sys/types.h> does not define. */
+#undef int32_t
+
+/* Define to `signed long long' if <sys/types.h> does not define. */
+#undef int64_t
+
+/* Define to `signed char' if <sys/types.h> does not define. */
+#undef int8_t
+
+/* Define to `unsigned short' if <sys/types.h> does not define. */
+#undef uint16_t
+
+/* Define to `unsigned long' if <sys/types.h> does not define. */
+#undef uint32_t
+
+/* Define to `unsigned long long' if <sys/types.h> does not define. */
+#undef uint64_t
+
+/* Define to `unsigned char' if <sys/types.h> does not define. */
+#undef uint8_t
diff --git a/icu/source/common/icudataver.c b/icu/source/common/icudataver.c
new file mode 100644
index 0000000..51fe9ce
--- /dev/null
+++ b/icu/source/common/icudataver.c
@@ -0,0 +1,83 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 2009, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/icudataver.h"
+#include "unicode/uversion.h"
+#include "unicode/ures.h"
+#include "uresimp.h" /* for ures_getVersionByKey */
+#include "cmemory.h"
+
+/*
+ * Determines if icustd is in the data.
+ */
+static UBool hasICUSTDBundle();
+
+static UBool hasICUSTDBundle() {
+    UErrorCode status = U_ZERO_ERROR;
+    UBool result = TRUE;
+    
+    UResourceBundle *icustdbundle = ures_openDirect(NULL, U_ICU_STD_BUNDLE, &status);
+    if (U_SUCCESS(status)) {
+        result = TRUE;
+    } else {
+        result = FALSE;
+    }
+    
+    ures_close(icustdbundle);
+    
+    return result;
+}
+
+U_CAPI void U_EXPORT2 u_getDataVersion(UVersionInfo dataVersionFillin, UErrorCode *status) {
+    UResourceBundle *icudatares = NULL;
+    
+    if (U_FAILURE(*status)) {
+        return;
+    }
+    
+    if (dataVersionFillin != NULL) {
+        icudatares = ures_openDirect(NULL, U_ICU_VERSION_BUNDLE , status);
+        if (U_SUCCESS(*status)) {
+            ures_getVersionByKey(icudatares, U_ICU_DATA_KEY, dataVersionFillin, status);
+        }
+        ures_close(icudatares);
+    }
+}
+
+U_CAPI UBool U_EXPORT2 u_isDataOlder(UVersionInfo dataVersionFillin, UBool *isModifiedFillin, UErrorCode *status) {
+    UBool result = TRUE;
+    UVersionInfo dataVersion;
+    UVersionInfo wiredVersion;
+    
+    if (U_FAILURE(*status)) {
+        return result;
+    }
+    
+    u_getDataVersion(dataVersion, status);
+    if (U_SUCCESS(*status)) {
+        u_versionFromString(wiredVersion, U_ICU_DATA_VERSION);
+        
+        if (uprv_memcmp(dataVersion, wiredVersion, sizeof(UVersionInfo)) >= 0) {
+            result = FALSE;
+        }
+        
+        if (dataVersionFillin != NULL) {
+            uprv_memcpy(dataVersionFillin, dataVersion, sizeof(UVersionInfo));
+        }
+        
+        if (hasICUSTDBundle()) {
+            *isModifiedFillin = FALSE;
+        } else {
+            *isModifiedFillin = TRUE;
+        }
+    }
+    
+    return result;
+}
diff --git a/icu/source/common/icuplug.c b/icu/source/common/icuplug.c
new file mode 100644
index 0000000..4fd77f3
--- /dev/null
+++ b/icu/source/common/icuplug.c
@@ -0,0 +1,825 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 2009-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+*  FILE NAME : icuplug.c
+*
+*   Date         Name        Description
+*   10/29/2009   sl          New.
+******************************************************************************
+*/
+
+#include "unicode/icuplug.h"
+#include "icuplugimp.h"
+#include "cstring.h"
+#include "cmemory.h"
+#include "putilimp.h"
+#include "ucln.h"
+#include <stdio.h>
+
+#ifndef UPLUG_TRACE
+#define UPLUG_TRACE 0
+#endif
+
+#if UPLUG_TRACE
+#include <stdio.h>
+#define DBG(x) fprintf(stderr, "%s:%d: ",__FILE__,__LINE__); fprintf x
+#endif
+
+/**
+ * Internal structure of an ICU plugin. 
+ */
+
+struct UPlugData {
+  UPlugEntrypoint  *entrypoint; /**< plugin entrypoint */
+  uint32_t structSize;    /**< initialized to the size of this structure */
+  uint32_t token;         /**< must be U_PLUG_TOKEN */
+  void *lib;              /**< plugin library, or NULL */
+  char libName[UPLUG_NAME_MAX];   /**< library name */
+  char sym[UPLUG_NAME_MAX];        /**< plugin symbol, or NULL */
+  char config[UPLUG_NAME_MAX];     /**< configuration data */
+  void *context;          /**< user context data */
+  char name[UPLUG_NAME_MAX];   /**< name of plugin */
+  UPlugLevel  level; /**< level of plugin */
+  UBool   awaitingLoad; /**< TRUE if the plugin is awaiting a load call */
+  UBool   dontUnload; /**< TRUE if plugin must stay resident (leak plugin and lib) */
+  UErrorCode pluginStatus; /**< status code of plugin */
+};
+
+
+
+#define UPLUG_LIBRARY_INITIAL_COUNT 8
+#define UPLUG_PLUGIN_INITIAL_COUNT 12
+
+/**
+ * Remove an item
+ * @param list the full list
+ * @param listSize the number of entries in the list
+ * @param memberSize the size of one member
+ * @param itemToRemove the item number of the member
+ * @return the new listsize 
+ */
+static int32_t uplug_removeEntryAt(void *list, int32_t listSize, int32_t memberSize, int32_t itemToRemove) {
+  uint8_t *bytePtr = (uint8_t *)list;
+    
+  /* get rid of some bad cases first */
+  if(listSize<1) {
+    return listSize;
+  }
+    
+  /* is there anything to move? */
+  if(listSize > itemToRemove+1) {
+    memmove(bytePtr+(itemToRemove*memberSize), bytePtr+((itemToRemove+1)*memberSize), memberSize);
+  }
+    
+  return listSize-1;
+}
+
+
+
+
+#if U_ENABLE_DYLOAD
+/**
+ * Library management. Internal. 
+ * @internal
+ */
+struct UPlugLibrary;
+
+/**
+ * Library management. Internal. 
+ * @internal
+ */
+typedef struct UPlugLibrary {
+  void *lib;                           /**< library ptr */
+  char name[UPLUG_NAME_MAX]; /**< library name */
+  uint32_t ref;                        /**< reference count */
+} UPlugLibrary;
+
+static UPlugLibrary   staticLibraryList[UPLUG_LIBRARY_INITIAL_COUNT];
+static UPlugLibrary * libraryList = staticLibraryList;
+static int32_t libraryCount = 0;
+static int32_t libraryMax = UPLUG_LIBRARY_INITIAL_COUNT;
+
+/**
+ * Search for a library. Doesn't lock
+ * @param libName libname to search for
+ * @return the library's struct
+ */
+static int32_t searchForLibraryName(const char *libName) {
+  int32_t i;
+    
+  for(i=0;i<libraryCount;i++) {
+    if(!uprv_strcmp(libName, libraryList[i].name)) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+static int32_t searchForLibrary(void *lib) {
+  int32_t i;
+    
+  for(i=0;i<libraryCount;i++) {
+    if(lib==libraryList[i].lib) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+U_INTERNAL char * U_EXPORT2
+uplug_findLibrary(void *lib, UErrorCode *status) {
+  int32_t libEnt;
+  char *ret = NULL;
+  if(U_FAILURE(*status)) {
+    return NULL;
+  }
+  libEnt = searchForLibrary(lib);
+  if(libEnt!=-1) { 
+    ret = libraryList[libEnt].name;
+  } else {
+    *status = U_MISSING_RESOURCE_ERROR;
+  }
+  return ret;
+}
+
+U_INTERNAL void * U_EXPORT2
+uplug_openLibrary(const char *libName, UErrorCode *status) {
+  int32_t libEntry = -1;
+  void *lib = NULL;
+    
+  if(U_FAILURE(*status)) return NULL;
+
+  libEntry = searchForLibraryName(libName);
+  if(libEntry == -1) {
+    libEntry = libraryCount++;
+    if(libraryCount >= libraryMax) {
+      /* Ran out of library slots. Statically allocated because we can't depend on allocating memory.. */
+      *status = U_MEMORY_ALLOCATION_ERROR;
+#if UPLUG_TRACE
+      DBG((stderr, "uplug_openLibrary() - out of library slots (max %d)\n", libraryMax));
+#endif
+      return NULL;
+    }
+    /* Some operating systems don't want 
+       DL operations from multiple threads. */
+    libraryList[libEntry].lib = uprv_dl_open(libName, status);
+#if UPLUG_TRACE
+    DBG((stderr, "uplug_openLibrary(%s,%s) libEntry %d, lib %p\n", libName, u_errorName(*status), libEntry, lib));
+#endif
+        
+    if(libraryList[libEntry].lib == NULL || U_FAILURE(*status)) {
+      /* cleanup. */
+      libraryList[libEntry].lib = NULL; /* failure with open */
+      libraryList[libEntry].name[0] = 0;
+#if UPLUG_TRACE
+      DBG((stderr, "uplug_openLibrary(%s,%s) libEntry %d, lib %p\n", libName, u_errorName(*status), libEntry, lib));
+#endif
+      /* no need to free - just won't increase the count. */
+      libraryCount--;
+    } else { /* is it still there? */
+      /* link it in */
+      uprv_strncpy(libraryList[libEntry].name,libName,UPLUG_NAME_MAX);
+      libraryList[libEntry].ref=1;
+      lib = libraryList[libEntry].lib;
+    }
+
+  } else {
+    lib = libraryList[libEntry].lib;
+    libraryList[libEntry].ref++;
+  }
+  return lib;
+}
+
+U_INTERNAL void U_EXPORT2
+uplug_closeLibrary(void *lib, UErrorCode *status) {
+  int32_t i;
+    
+#if UPLUG_TRACE
+  DBG((stderr, "uplug_closeLibrary(%p,%s) list %p\n", lib, u_errorName(*status), (void*)libraryList));
+#endif
+  if(U_FAILURE(*status)) return;
+    
+  for(i=0;i<libraryCount;i++) {
+    if(lib==libraryList[i].lib) {
+      if(--(libraryList[i].ref) == 0) {
+        uprv_dl_close(libraryList[i].lib, status);
+        libraryCount = uplug_removeEntryAt(libraryList, libraryCount, sizeof(*libraryList), i);
+      }
+      return;
+    }
+  }
+  *status = U_INTERNAL_PROGRAM_ERROR; /* could not find the entry! */
+}
+
+#endif
+
+static UPlugData pluginList[UPLUG_PLUGIN_INITIAL_COUNT];
+static int32_t pluginCount = 0;
+
+
+
+  
+static int32_t uplug_pluginNumber(UPlugData* d) {
+  UPlugData *pastPlug = &pluginList[pluginCount];
+  if(d<=pluginList) {
+    return 0;
+  } else if(d>=pastPlug) {
+    return pluginCount;
+  } else {
+    return (d-pluginList)/sizeof(pluginList[0]);
+  }
+}
+
+
+U_CAPI UPlugData * U_EXPORT2
+uplug_nextPlug(UPlugData *prior) {
+  if(prior==NULL) {
+    return pluginList;
+  } else {
+    UPlugData *nextPlug = &prior[1];
+    UPlugData *pastPlug = &pluginList[pluginCount];
+    
+    if(nextPlug>=pastPlug) {
+      return NULL;
+    } else {
+      return nextPlug;
+    }
+  }
+}
+
+
+
+/**
+ * Call the plugin with some params
+ */
+static void uplug_callPlug(UPlugData *plug, UPlugReason reason, UErrorCode *status) {
+  UPlugTokenReturn token;
+  if(plug==NULL||U_FAILURE(*status)) {
+    return;
+  }
+  token = (*(plug->entrypoint))(plug, reason, status);
+  if(token!=UPLUG_TOKEN) {
+    *status = U_INTERNAL_PROGRAM_ERROR;
+  }
+}
+
+
+static void uplug_unloadPlug(UPlugData *plug, UErrorCode *status) {
+  if(plug->awaitingLoad) {  /* shouldn't happen. Plugin hasn'tbeen loaded yet.*/
+    *status = U_INTERNAL_PROGRAM_ERROR;
+    return; 
+  }
+  if(U_SUCCESS(plug->pluginStatus)) {
+    /* Don't unload a plug which has a failing load status - means it didn't actually load. */
+    uplug_callPlug(plug, UPLUG_REASON_UNLOAD, status);
+  }
+}
+
+static void uplug_queryPlug(UPlugData *plug, UErrorCode *status) {
+  if(!plug->awaitingLoad || !(plug->level == UPLUG_LEVEL_UNKNOWN) ) {  /* shouldn't happen. Plugin hasn'tbeen loaded yet.*/
+    *status = U_INTERNAL_PROGRAM_ERROR;
+    return; 
+  }
+  plug->level = UPLUG_LEVEL_INVALID;
+  uplug_callPlug(plug, UPLUG_REASON_QUERY, status);
+  if(U_SUCCESS(*status)) { 
+    if(plug->level == UPLUG_LEVEL_INVALID) {
+      plug->pluginStatus = U_PLUGIN_DIDNT_SET_LEVEL;
+      plug->awaitingLoad = FALSE;
+    }
+  } else {
+    plug->pluginStatus = U_INTERNAL_PROGRAM_ERROR;
+    plug->awaitingLoad = FALSE;
+  }
+}
+
+
+static void uplug_loadPlug(UPlugData *plug, UErrorCode *status) {
+  if(!plug->awaitingLoad || (plug->level < UPLUG_LEVEL_LOW) ) {  /* shouldn't happen. Plugin hasn'tbeen loaded yet.*/
+    *status = U_INTERNAL_PROGRAM_ERROR;
+    return;
+  }
+  uplug_callPlug(plug, UPLUG_REASON_LOAD, status);
+  plug->awaitingLoad = FALSE;
+  if(!U_SUCCESS(*status)) {
+    plug->pluginStatus = U_INTERNAL_PROGRAM_ERROR;
+  }
+}
+
+static UPlugData *uplug_allocateEmptyPlug(UErrorCode *status)
+{
+  UPlugData *plug = NULL;
+
+  if(U_FAILURE(*status)) {
+    return NULL;
+  }
+
+  if(pluginCount == UPLUG_PLUGIN_INITIAL_COUNT) {
+    *status = U_MEMORY_ALLOCATION_ERROR;
+    return NULL;
+  }
+
+  plug = &pluginList[pluginCount++];
+
+  plug->token = UPLUG_TOKEN;
+  plug->structSize = sizeof(UPlugData);
+  plug->name[0]=0;
+  plug->level = UPLUG_LEVEL_UNKNOWN; /* initialize to null state */
+  plug->awaitingLoad = TRUE;
+  plug->dontUnload = FALSE;
+  plug->pluginStatus = U_ZERO_ERROR;
+  plug->libName[0] = 0;
+  plug->config[0]=0;
+  plug->sym[0]=0;
+  plug->lib=NULL;
+  plug->entrypoint=NULL;
+
+
+  return plug;
+}
+
+static UPlugData *uplug_allocatePlug(UPlugEntrypoint *entrypoint, const char *config, void *lib, const char *symName,
+                                     UErrorCode *status) {
+  UPlugData *plug;
+
+  if(U_FAILURE(*status)) {
+    return NULL;
+  }
+
+  plug = uplug_allocateEmptyPlug(status);
+  if(config!=NULL) {
+    uprv_strncpy(plug->config, config, UPLUG_NAME_MAX);
+  } else {
+    plug->config[0] = 0;
+  }
+    
+  if(symName!=NULL) {
+    uprv_strncpy(plug->sym, symName, UPLUG_NAME_MAX);
+  } else {
+    plug->sym[0] = 0;
+  }
+    
+  plug->entrypoint = entrypoint;
+  plug->lib = lib;
+  uplug_queryPlug(plug, status);
+    
+  return plug;
+}
+
+static void uplug_deallocatePlug(UPlugData *plug, UErrorCode *status) {
+  UErrorCode subStatus = U_ZERO_ERROR;
+  if(!plug->dontUnload) {
+#if U_ENABLE_DYLOAD
+    uplug_closeLibrary(plug->lib, &subStatus);
+#endif
+  }
+  plug->lib = NULL;
+  if(U_SUCCESS(*status) && U_FAILURE(subStatus)) {
+    *status = subStatus;
+  }
+  /* shift plugins up and decrement count. */
+  if(U_SUCCESS(*status)) {
+    /* all ok- remove. */
+    pluginCount = uplug_removeEntryAt(pluginList, pluginCount, sizeof(plug[0]), uplug_pluginNumber(plug));
+  } else {
+    /* not ok- leave as a message. */
+    plug->awaitingLoad=FALSE;
+    plug->entrypoint=0;
+    plug->dontUnload=TRUE;
+  }
+}
+
+static void uplug_doUnloadPlug(UPlugData *plugToRemove, UErrorCode *status) {
+  if(plugToRemove != NULL) {
+    uplug_unloadPlug(plugToRemove, status);
+    uplug_deallocatePlug(plugToRemove, status);
+  }
+}
+
+U_CAPI void U_EXPORT2
+uplug_removePlug(UPlugData *plug, UErrorCode *status)  {
+  UPlugData *cursor = NULL;
+  UPlugData *plugToRemove = NULL;
+  if(U_FAILURE(*status)) return;
+    
+  for(cursor=pluginList;cursor!=NULL;) {
+    if(cursor==plug) {
+      plugToRemove = plug;
+      cursor=NULL;
+    } else {
+      cursor = uplug_nextPlug(cursor);
+    }
+  }
+    
+  uplug_doUnloadPlug(plugToRemove, status);
+}
+
+
+
+
+U_CAPI void U_EXPORT2 
+uplug_setPlugNoUnload(UPlugData *data, UBool dontUnload)
+{
+  data->dontUnload = dontUnload;
+}
+
+
+U_CAPI void U_EXPORT2
+uplug_setPlugLevel(UPlugData *data, UPlugLevel level) {
+  data->level = level;
+}
+
+
+U_CAPI UPlugLevel U_EXPORT2
+uplug_getPlugLevel(UPlugData *data) {
+  return data->level;
+}
+
+
+U_CAPI void U_EXPORT2
+uplug_setPlugName(UPlugData *data, const char *name) {
+  uprv_strncpy(data->name, name, UPLUG_NAME_MAX);
+}
+
+
+U_CAPI const char * U_EXPORT2
+uplug_getPlugName(UPlugData *data) {
+  return data->name;
+}
+
+
+U_CAPI const char * U_EXPORT2
+uplug_getSymbolName(UPlugData *data) {
+  return data->sym;
+}
+
+U_CAPI const char * U_EXPORT2
+uplug_getLibraryName(UPlugData *data, UErrorCode *status) {
+  if(data->libName[0]) {
+    return data->libName;
+  } else {
+#if U_ENABLE_DYLOAD
+    return uplug_findLibrary(data->lib, status);
+#else
+    return NULL;
+#endif
+  }
+}
+
+U_CAPI void * U_EXPORT2
+uplug_getLibrary(UPlugData *data) {
+  return data->lib;
+}
+
+U_CAPI void * U_EXPORT2
+uplug_getContext(UPlugData *data) {
+  return data->context;
+}
+
+
+U_CAPI void U_EXPORT2
+uplug_setContext(UPlugData *data, void *context) {
+  data->context = context;
+}
+
+U_CAPI const char* U_EXPORT2
+uplug_getConfiguration(UPlugData *data) {
+  return data->config;
+}
+
+U_INTERNAL UPlugData* U_EXPORT2
+uplug_getPlugInternal(int32_t n) { 
+  if(n <0 || n >= pluginCount) {
+    return NULL;
+  } else { 
+    return &(pluginList[n]);
+  }
+}
+
+
+U_CAPI UErrorCode U_EXPORT2
+uplug_getPlugLoadStatus(UPlugData *plug) {
+  return plug->pluginStatus;
+}
+
+
+
+
+/**
+ * Initialize a plugin fron an entrypoint and library - but don't load it.
+ */
+static UPlugData* uplug_initPlugFromEntrypointAndLibrary(UPlugEntrypoint *entrypoint, const char *config, void *lib, const char *sym,
+                                                         UErrorCode *status) {
+  UPlugData *plug = NULL;
+
+  plug = uplug_allocatePlug(entrypoint, config, lib, sym, status);
+
+  if(U_SUCCESS(*status)) {
+    return plug;
+  } else {
+    uplug_deallocatePlug(plug, status);
+    return NULL;
+  }
+}
+
+U_CAPI UPlugData* U_EXPORT2
+uplug_loadPlugFromEntrypoint(UPlugEntrypoint *entrypoint, const char *config, UErrorCode *status) {
+  UPlugData* plug = uplug_initPlugFromEntrypointAndLibrary(entrypoint, config, NULL, NULL, status);
+  uplug_loadPlug(plug, status);
+  return plug;
+}
+
+
+static UPlugData* 
+uplug_initErrorPlug(const char *libName, const char *sym, const char *config, const char *nameOrError, UErrorCode loadStatus, UErrorCode *status)
+{
+  UPlugData *plug = uplug_allocateEmptyPlug(status);
+  if(U_FAILURE(*status)) return NULL;
+
+  plug->pluginStatus = loadStatus;
+  plug->awaitingLoad = FALSE; /* Won't load. */
+  plug->dontUnload = TRUE; /* cannot unload. */
+
+  if(sym!=NULL) {
+    uprv_strncpy(plug->sym, sym, UPLUG_NAME_MAX);
+  }
+
+  if(libName!=NULL) {
+    uprv_strncpy(plug->libName, libName, UPLUG_NAME_MAX);
+  }
+
+  if(nameOrError!=NULL) {
+    uprv_strncpy(plug->name, nameOrError, UPLUG_NAME_MAX);
+  }
+
+  if(config!=NULL) {
+    uprv_strncpy(plug->config, config, UPLUG_NAME_MAX);
+  }
+
+  return plug;
+}
+
+/**
+ * Fetch a plugin from DLL, and then initialize it from a library- but don't load it.
+ */
+
+#if U_ENABLE_DYLOAD
+
+static UPlugData* 
+uplug_initPlugFromLibrary(const char *libName, const char *sym, const char *config, UErrorCode *status) {
+  void *lib = NULL;
+  UPlugData *plug = NULL;
+  if(U_FAILURE(*status)) { return NULL; }
+  lib = uplug_openLibrary(libName, status);
+  if(lib!=NULL && U_SUCCESS(*status)) {
+    UPlugEntrypoint *entrypoint = NULL;
+    /*
+     * ISO forbids the following cast.
+     *  See: http://www.trilithium.com/johan/2004/12/problem-with-dlsym/ 
+     */
+    entrypoint = (UPlugEntrypoint*)uprv_dl_sym(lib, sym, status);
+      
+    if(entrypoint!=NULL&&U_SUCCESS(*status)) {
+      plug = uplug_initPlugFromEntrypointAndLibrary(entrypoint, config, lib, sym, status);
+      if(plug!=NULL&&U_SUCCESS(*status)) {
+        plug->lib = lib; /* plug takes ownership of library */
+        lib = NULL; /* library is now owned by plugin. */
+      }
+    } else {
+      UErrorCode subStatus = U_ZERO_ERROR;
+      plug = uplug_initErrorPlug(libName,sym,config,"ERROR: Could not load entrypoint",(lib==NULL)?U_MISSING_RESOURCE_ERROR:*status,&subStatus);
+    }
+    if(lib!=NULL) { /* still need to close the lib */
+      UErrorCode subStatus = U_ZERO_ERROR;
+      uplug_closeLibrary(lib, &subStatus); /* don't care here */
+    }
+  } else {
+    UErrorCode subStatus = U_ZERO_ERROR;
+    plug = uplug_initErrorPlug(libName,sym,config,"ERROR: could not load library",(lib==NULL)?U_MISSING_RESOURCE_ERROR:*status,&subStatus);
+  }
+  return plug;
+}
+
+U_CAPI UPlugData* U_EXPORT2
+uplug_loadPlugFromLibrary(const char *libName, const char *sym, const char *config, UErrorCode *status) { 
+  UPlugData *plug = NULL;
+  if(U_FAILURE(*status)) { return NULL; }
+  plug = uplug_initPlugFromLibrary(libName, sym, config, status);
+  uplug_loadPlug(plug, status);
+
+  return plug;
+}
+
+#endif
+
+U_CAPI UPlugLevel U_EXPORT2 uplug_getCurrentLevel() {
+  if(cmemory_inUse()) {
+    return UPLUG_LEVEL_HIGH;
+  } else {
+    return UPLUG_LEVEL_LOW;
+  }
+}
+
+static UBool U_CALLCONV uplug_cleanup(void)
+{
+  int32_t i;
+    
+  UPlugData *pluginToRemove;
+  /* cleanup plugs */
+  for(i=0;i<pluginCount;i++) {
+    UErrorCode subStatus = U_ZERO_ERROR;
+    pluginToRemove = &pluginList[i];
+    /* unload and deallocate */
+    uplug_doUnloadPlug(pluginToRemove, &subStatus);
+  }
+  /* close other held libs? */
+  return TRUE;
+}
+
+static void uplug_loadWaitingPlugs(UErrorCode *status) {
+  int32_t i;
+  UPlugLevel currentLevel = uplug_getCurrentLevel();
+    
+  if(U_FAILURE(*status)) {
+    return;
+  }
+#if UPLUG_TRACE
+  DBG((stderr,  "uplug_loadWaitingPlugs() Level: %d\n", currentLevel));
+#endif
+  /* pass #1: low level plugs */
+  for(i=0;i<pluginCount;i++) {
+    UErrorCode subStatus = U_ZERO_ERROR;
+    UPlugData *pluginToLoad = &pluginList[i];
+    if(pluginToLoad->awaitingLoad) {
+      if(pluginToLoad->level == UPLUG_LEVEL_LOW) {
+        if(currentLevel > UPLUG_LEVEL_LOW) {
+          pluginToLoad->pluginStatus = U_PLUGIN_TOO_HIGH;
+        } else {
+          UPlugLevel newLevel;
+          uplug_loadPlug(pluginToLoad, &subStatus);
+          newLevel = uplug_getCurrentLevel();
+          if(newLevel > currentLevel) {
+            pluginToLoad->pluginStatus = U_PLUGIN_CHANGED_LEVEL_WARNING;
+            currentLevel = newLevel;
+          }
+        }
+        pluginToLoad->awaitingLoad = FALSE;
+      } 
+    }
+  }
+  currentLevel = uplug_getCurrentLevel();
+    
+  for(i=0;i<pluginCount;i++) {
+    UErrorCode subStatus = U_ZERO_ERROR;
+    UPlugData *pluginToLoad = &pluginList[i];
+        
+    if(pluginToLoad->awaitingLoad) {
+      if(pluginToLoad->level == UPLUG_LEVEL_INVALID) { 
+        pluginToLoad->pluginStatus = U_PLUGIN_DIDNT_SET_LEVEL;
+      } else if(pluginToLoad->level == UPLUG_LEVEL_UNKNOWN) {
+        pluginToLoad->pluginStatus = U_INTERNAL_PROGRAM_ERROR;
+      } else {
+        uplug_loadPlug(pluginToLoad, &subStatus);
+      }
+      pluginToLoad->awaitingLoad = FALSE;
+    }
+  }
+    
+#if UPLUG_TRACE
+  DBG((stderr,  " Done Loading Plugs. Level: %d\n", (int32_t)uplug_getCurrentLevel()));
+#endif
+}
+
+#if U_ENABLE_DYLOAD
+/* Name of the plugin config file */
+static char plugin_file[2048] = "";
+#endif
+
+U_INTERNAL const char* U_EXPORT2
+uplug_getPluginFile() {
+#if U_ENABLE_DYLOAD
+  return plugin_file;
+#else
+  return NULL;
+#endif
+}
+
+
+U_CAPI void U_EXPORT2
+uplug_init(UErrorCode *status) {
+#if !U_ENABLE_DYLOAD
+  (void)status; /* unused */
+#else
+  const char *plugin_dir;
+
+  if(U_FAILURE(*status)) return;
+  plugin_dir = getenv("ICU_PLUGINS");
+
+#if defined(DEFAULT_ICU_PLUGINS) 
+  if(plugin_dir == NULL || !*plugin_dir) {
+    plugin_dir = DEFAULT_ICU_PLUGINS;
+  }
+#endif
+
+#if UPLUG_TRACE
+  DBG((stderr, "ICU_PLUGINS=%s\n", plugin_dir));
+#endif
+
+  if(plugin_dir != NULL && *plugin_dir) {
+    FILE *f;
+        
+        
+    uprv_strncpy(plugin_file, plugin_dir, 2047);
+    uprv_strncat(plugin_file, U_FILE_SEP_STRING,2047);
+    uprv_strncat(plugin_file, "icuplugins",2047);
+    uprv_strncat(plugin_file, U_ICU_VERSION_SHORT ,2047);
+    uprv_strncat(plugin_file, ".txt" ,2047);
+        
+#if UPLUG_TRACE
+    DBG((stderr, "pluginfile= %s\n", plugin_file));
+#endif
+        
+    f = fopen(plugin_file, "r");
+
+    if(f != NULL) {
+      char linebuf[1024];
+      char *p, *libName=NULL, *symName=NULL, *config=NULL;
+      int32_t line = 0;
+            
+            
+      while(fgets(linebuf,1023,f)) {
+        line++;
+
+        if(!*linebuf || *linebuf=='#') {
+          continue;
+        } else {
+          p = linebuf;
+          while(*p&&isspace(*p))
+            p++;
+          if(!*p || *p=='#') continue;
+          libName = p;
+          while(*p&&!isspace(*p)) {
+            p++;
+          }
+          if(!*p || *p=='#') continue; /* no tab after libname */
+          *p=0; /* end of libname */
+          p++;
+          while(*p&&isspace(*p)) {
+            p++;
+          }
+          if(!*p||*p=='#') continue; /* no symname after libname +tab */
+          symName = p;
+          while(*p&&!isspace(*p)) {
+            p++;
+          }
+                    
+          if(*p) { /* has config */
+            *p=0;
+            ++p;
+            while(*p&&isspace(*p)) {
+              p++;
+            }
+            if(*p) {
+              config = p;
+            }
+          }
+                    
+          /* chop whitespace at the end of the config */
+          if(config!=NULL&&*config!=0) {
+            p = config+strlen(config);
+            while(p>config&&isspace(*(--p))) {
+              *p=0;
+            }
+          }
+                
+          /* OK, we're good. */
+          { 
+            UErrorCode subStatus = U_ZERO_ERROR;
+            UPlugData *plug = uplug_initPlugFromLibrary(libName, symName, config, &subStatus);
+            if(U_FAILURE(subStatus) && U_SUCCESS(*status)) {
+              *status = subStatus;
+            }
+#if UPLUG_TRACE
+            DBG((stderr, "PLUGIN libName=[%s], sym=[%s], config=[%s]\n", libName, symName, config));
+            DBG((stderr, " -> %p, %s\n", (void*)plug, u_errorName(subStatus)));
+#else
+            (void)plug; /* unused */
+#endif
+          }
+        }
+      }
+    } else {
+#if UPLUG_TRACE
+      DBG((stderr, "Can't open plugin file %s\n", plugin_file));
+#endif
+    }
+  }
+  uplug_loadWaitingPlugs(status);
+#endif /* U_ENABLE_DYLOAD */
+  ucln_registerCleanup(UCLN_UPLUG, uplug_cleanup);
+}
diff --git a/icu/source/common/icuplugimp.h b/icu/source/common/icuplugimp.h
new file mode 100644
index 0000000..53b9c0c
--- /dev/null
+++ b/icu/source/common/icuplugimp.h
@@ -0,0 +1,87 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 2009-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+*  FILE NAME : icuplugimp.h
+* 
+*  Internal functions for the ICU plugin system
+*
+*   Date         Name        Description
+*   10/29/2009   sl          New.
+******************************************************************************
+*/
+
+
+#ifndef ICUPLUGIMP_H
+#define ICUPLUGIMP_H
+
+#include "unicode/icuplug.h"
+
+/*========================*/
+/** @{ Library Manipulation  
+ */
+
+/**
+ * Open a library, adding a reference count if needed.
+ * @param libName library name to load
+ * @param status error code
+ * @return the library pointer, or NULL
+ * @internal internal use only
+ */
+U_INTERNAL void * U_EXPORT2
+uplug_openLibrary(const char *libName, UErrorCode *status);
+
+/**
+ * Close a library, if its reference count is 0
+ * @param lib the library to close
+ * @param status error code
+ * @internal internal use only
+ */
+U_INTERNAL void U_EXPORT2
+uplug_closeLibrary(void *lib, UErrorCode *status);
+
+/**
+ * Get a library's name, or NULL if not found.
+ * @param lib the library's name
+ * @param status error code
+ * @return the library name, or NULL if not found.
+ * @internal internal use only
+ */
+U_INTERNAL  char * U_EXPORT2
+uplug_findLibrary(void *lib, UErrorCode *status);
+
+/** @} */
+
+/*========================*/
+/** {@ ICU Plugin internal interfaces
+ */
+
+/**
+ * Initialize the plugins 
+ * @param status error result
+ * @internal - Internal use only.
+ */
+U_INTERNAL void U_EXPORT2
+uplug_init(UErrorCode *status);
+
+/**
+ * Get raw plug N
+ * @internal - Internal use only
+ */ 
+U_INTERNAL UPlugData* U_EXPORT2
+uplug_getPlugInternal(int32_t n);
+
+/**
+ * Get the name of the plugin file. 
+ * @internal - Internal use only.
+ */
+U_INTERNAL const char* U_EXPORT2
+uplug_getPluginFile(void);
+
+/** @} */
+
+#endif
diff --git a/icu/source/common/localsvc.h b/icu/source/common/localsvc.h
new file mode 100644
index 0000000..67e5a84
--- /dev/null
+++ b/icu/source/common/localsvc.h
@@ -0,0 +1,25 @@
+/*
+***************************************************************************
+*   Copyright (C) 2006 International Business Machines Corporation        *
+*   and others. All rights reserved.                                      *
+***************************************************************************
+*/
+
+#ifndef LOCALSVC_H
+#define LOCALSVC_H
+
+#include "unicode/utypes.h"
+
+#if U_LOCAL_SERVICE_HOOK
+/**
+ * Prototype for user-supplied service hook. This function is expected to return
+ * a type of factory object specific to the requested service.
+ * 
+ * @param what service-specific string identifying the specific user hook
+ * @param status error status
+ * @return a service-specific hook, or NULL on failure.
+ */
+U_CAPI void* uprv_svc_hook(const char *what, UErrorCode *status);
+#endif
+
+#endif
diff --git a/icu/source/common/locavailable.cpp b/icu/source/common/locavailable.cpp
new file mode 100644
index 0000000..7060a68
--- /dev/null
+++ b/icu/source/common/locavailable.cpp
@@ -0,0 +1,187 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 1997-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  locavailable.cpp
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2010feb25
+*   created by: Markus W. Scherer
+*
+*   Code for available locales, separated out from other .cpp files
+*   that then do not depend on resource bundle code and res_index bundles.
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/locid.h"
+#include "unicode/uloc.h"
+#include "unicode/ures.h"
+#include "cmemory.h"
+#include "ucln_cmn.h"
+#include "umutex.h"
+#include "uresimp.h"
+
+// C++ API ----------------------------------------------------------------- ***
+
+static U_NAMESPACE_QUALIFIER Locale*  availableLocaleList = NULL;
+static int32_t  availableLocaleListCount;
+
+U_CDECL_BEGIN
+
+static UBool U_CALLCONV locale_available_cleanup(void)
+{
+    U_NAMESPACE_USE
+
+    if (availableLocaleList) {
+        delete []availableLocaleList;
+        availableLocaleList = NULL;
+    }
+    availableLocaleListCount = 0;
+
+    return TRUE;
+}
+
+U_CDECL_END
+
+U_NAMESPACE_BEGIN
+
+const Locale* U_EXPORT2
+Locale::getAvailableLocales(int32_t& count)
+{
+    // for now, there is a hardcoded list, so just walk through that list and set it up.
+    UBool needInit;
+    UMTX_CHECK(NULL, availableLocaleList == NULL, needInit);
+
+    if (needInit) {
+        int32_t locCount = uloc_countAvailable();
+        Locale *newLocaleList = 0;
+        if(locCount) {
+           newLocaleList = new Locale[locCount];
+        }
+        if (newLocaleList == NULL) {
+            count = 0;
+            return NULL;
+        }
+
+        count = locCount;
+
+        while(--locCount >= 0) {
+            newLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount));
+        }
+
+        umtx_lock(NULL);
+        if(availableLocaleList == 0) {
+            availableLocaleListCount = count;
+            availableLocaleList = newLocaleList;
+            newLocaleList = NULL;
+            ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE, locale_available_cleanup);
+        }
+        umtx_unlock(NULL);
+        delete []newLocaleList;
+    }
+    count = availableLocaleListCount;
+    return availableLocaleList;
+}
+
+
+U_NAMESPACE_END
+
+// C API ------------------------------------------------------------------- ***
+
+U_NAMESPACE_USE
+
+/* ### Constants **************************************************/
+
+/* These strings describe the resources we attempt to load from
+ the locale ResourceBundle data file.*/
+static const char _kIndexLocaleName[] = "res_index";
+static const char _kIndexTag[]        = "InstalledLocales";
+
+static char** _installedLocales = NULL;
+static int32_t _installedLocalesCount = 0;
+
+/* ### Get available **************************************************/
+
+static UBool U_CALLCONV uloc_cleanup(void) {
+    char ** temp;
+
+    if (_installedLocales) {
+        temp = _installedLocales;
+        _installedLocales = NULL;
+
+        _installedLocalesCount = 0;
+
+        uprv_free(temp);
+    }
+    return TRUE;
+}
+
+static void _load_installedLocales()
+{
+    UBool   localesLoaded;
+
+    UMTX_CHECK(NULL, _installedLocales != NULL, localesLoaded);
+    
+    if (localesLoaded == FALSE) {
+        UResourceBundle *indexLocale = NULL;
+        UResourceBundle installed;
+        UErrorCode status = U_ZERO_ERROR;
+        char ** temp;
+        int32_t i = 0;
+        int32_t localeCount;
+        
+        ures_initStackObject(&installed);
+        indexLocale = ures_openDirect(NULL, _kIndexLocaleName, &status);
+        ures_getByKey(indexLocale, _kIndexTag, &installed, &status);
+        
+        if(U_SUCCESS(status)) {
+            localeCount = ures_getSize(&installed);
+            temp = (char **) uprv_malloc(sizeof(char*) * (localeCount+1));
+            /* Check for null pointer */
+            if (temp != NULL) {
+                ures_resetIterator(&installed);
+                while(ures_hasNext(&installed)) {
+                    ures_getNextString(&installed, NULL, (const char **)&temp[i++], &status);
+                }
+                temp[i] = NULL;
+
+                umtx_lock(NULL);
+                if (_installedLocales == NULL)
+                {
+                    _installedLocalesCount = localeCount;
+                    _installedLocales = temp;
+                    temp = NULL;
+                    ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
+                } 
+                umtx_unlock(NULL);
+
+                uprv_free(temp);
+            }
+        }
+        ures_close(&installed);
+        ures_close(indexLocale);
+    }
+}
+
+U_CAPI const char* U_EXPORT2
+uloc_getAvailable(int32_t offset) 
+{
+    
+    _load_installedLocales();
+    
+    if (offset > _installedLocalesCount)
+        return NULL;
+    return _installedLocales[offset];
+}
+
+U_CAPI int32_t  U_EXPORT2
+uloc_countAvailable()
+{
+    _load_installedLocales();
+    return _installedLocalesCount;
+}
diff --git a/icu/source/common/locbased.cpp b/icu/source/common/locbased.cpp
new file mode 100644
index 0000000..e96b9f7
--- /dev/null
+++ b/icu/source/common/locbased.cpp
@@ -0,0 +1,46 @@
+/*
+**********************************************************************
+* Copyright (c) 2004, International Business Machines
+* Corporation and others.  All Rights Reserved.
+**********************************************************************
+* Author: Alan Liu
+* Created: January 16 2004
+* Since: ICU 2.8
+**********************************************************************
+*/
+#include "locbased.h"
+#include "cstring.h"
+
+U_NAMESPACE_BEGIN
+
+Locale LocaleBased::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
+    const char* id = getLocaleID(type, status);
+    return Locale((id != 0) ? id : "");
+}
+
+const char* LocaleBased::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const {
+    if (U_FAILURE(status)) {
+        return NULL;
+    }
+
+    switch(type) {
+    case ULOC_VALID_LOCALE:
+        return valid;
+    case ULOC_ACTUAL_LOCALE:
+        return actual;
+    default:
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return NULL;
+    }
+}
+
+void LocaleBased::setLocaleIDs(const char* validID, const char* actualID) {
+    if (validID != 0) {
+        uprv_strcpy(valid, validID);
+    }
+    if (actualID != 0) {
+        uprv_strcpy(actual, actualID);
+    }
+}
+
+U_NAMESPACE_END
diff --git a/icu/source/common/locbased.h b/icu/source/common/locbased.h
new file mode 100644
index 0000000..366b151
--- /dev/null
+++ b/icu/source/common/locbased.h
@@ -0,0 +1,97 @@
+/*
+**********************************************************************
+* Copyright (c) 2004, International Business Machines
+* Corporation and others.  All Rights Reserved.
+**********************************************************************
+* Author: Alan Liu
+* Created: January 16 2004
+* Since: ICU 2.8
+**********************************************************************
+*/
+#ifndef LOCBASED_H
+#define LOCBASED_H
+
+#include "unicode/locid.h"
+#include "unicode/uobject.h"
+
+/**
+ * Macro to declare a locale LocaleBased wrapper object for the given
+ * object, which must have two members named `validLocale' and
+ * `actualLocale'.
+ */
+#define U_LOCALE_BASED(varname, objname) \
+  LocaleBased varname((objname).validLocale, (objname).actualLocale);
+
+U_NAMESPACE_BEGIN
+
+/**
+ * A utility class that unifies the implementation of getLocale() by
+ * various ICU services.  This class is likely to be removed in the
+ * ICU 3.0 time frame in favor of an integrated approach with the
+ * services framework.
+ * @since ICU 2.8
+ */
+class U_COMMON_API LocaleBased : public UMemory {
+
+ public:
+
+    /**
+     * Construct a LocaleBased wrapper around the two pointers.  These
+     * will be aliased for the lifetime of this object.
+     */
+    inline LocaleBased(char* validAlias, char* actualAlias);
+
+    /**
+     * Construct a LocaleBased wrapper around the two const pointers.
+     * These will be aliased for the lifetime of this object.
+     */
+    inline LocaleBased(const char* validAlias, const char* actualAlias);
+
+    /**
+     * Return locale meta-data for the service object wrapped by this
+     * object.  Either the valid or the actual locale may be
+     * retrieved.
+     * @param type either ULOC_VALID_LOCALE or ULOC_ACTUAL_LOCALE
+     * @param status input-output error code
+     * @return the indicated locale
+     */
+    Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const;
+
+    /**
+     * Return the locale ID for the service object wrapped by this
+     * object.  Either the valid or the actual locale may be
+     * retrieved.
+     * @param type either ULOC_VALID_LOCALE or ULOC_ACTUAL_LOCALE
+     * @param status input-output error code
+     * @return the indicated locale ID
+     */
+    const char* getLocaleID(ULocDataLocaleType type, UErrorCode& status) const;
+
+    /**
+     * Set the locale meta-data for the service object wrapped by this
+     * object.  If either parameter is zero, it is ignored.
+     * @param valid the ID of the valid locale
+     * @param actual the ID of the actual locale
+     */
+    void setLocaleIDs(const char* valid, const char* actual);
+
+ private:
+
+    char* valid;
+    
+    char* actual;
+};
+
+inline LocaleBased::LocaleBased(char* validAlias, char* actualAlias) :
+    valid(validAlias), actual(actualAlias) {
+}
+
+inline LocaleBased::LocaleBased(const char* validAlias,
+                                const char* actualAlias) :
+    // ugh: cast away const
+    valid((char*)validAlias), actual((char*)actualAlias) {
+}
+
+U_NAMESPACE_END
+
+#endif
diff --git a/icu/source/common/locdispnames.cpp b/icu/source/common/locdispnames.cpp
new file mode 100644
index 0000000..c3362d3
--- /dev/null
+++ b/icu/source/common/locdispnames.cpp
@@ -0,0 +1,824 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 1997-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  locdispnames.cpp
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2010feb25
+*   created by: Markus W. Scherer
+*
+*   Code for locale display names, separated out from other .cpp files
+*   that then do not depend on resource bundle code and display name data.
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/brkiter.h"
+#include "unicode/locid.h"
+#include "unicode/uloc.h"
+#include "unicode/ures.h"
+#include "unicode/ustring.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "putilimp.h"
+#include "ulocimp.h"
+#include "uresimp.h"
+#include "ureslocs.h"
+#include "ustr_imp.h"
+
+// C++ API ----------------------------------------------------------------- ***
+
+U_NAMESPACE_BEGIN
+
+UnicodeString&
+Locale::getDisplayLanguage(UnicodeString& dispLang) const
+{
+    return this->getDisplayLanguage(getDefault(), dispLang);
+}
+
+/*We cannot make any assumptions on the size of the output display strings
+* Yet, since we are calling through to a C API, we need to set limits on
+* buffer size. For all the following getDisplay functions we first attempt
+* to fill up a stack allocated buffer. If it is to small we heap allocated
+* the exact buffer we need copy it to the UnicodeString and delete it*/
+
+UnicodeString&
+Locale::getDisplayLanguage(const Locale &displayLocale,
+                           UnicodeString &result) const {
+    UChar *buffer;
+    UErrorCode errorCode=U_ZERO_ERROR;
+    int32_t length;
+
+    buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
+    if(buffer==0) {
+        result.truncate(0);
+        return result;
+    }
+
+    length=uloc_getDisplayLanguage(fullName, displayLocale.fullName,
+                                   buffer, result.getCapacity(),
+                                   &errorCode);
+    result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
+
+    if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
+        buffer=result.getBuffer(length);
+        if(buffer==0) {
+            result.truncate(0);
+            return result;
+        }
+        errorCode=U_ZERO_ERROR;
+        length=uloc_getDisplayLanguage(fullName, displayLocale.fullName,
+                                       buffer, result.getCapacity(),
+                                       &errorCode);
+        result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
+    }
+
+    return result;
+}
+
+UnicodeString&
+Locale::getDisplayScript(UnicodeString& dispScript) const
+{
+    return this->getDisplayScript(getDefault(), dispScript);
+}
+
+UnicodeString&
+Locale::getDisplayScript(const Locale &displayLocale,
+                          UnicodeString &result) const {
+    UChar *buffer;
+    UErrorCode errorCode=U_ZERO_ERROR;
+    int32_t length;
+
+    buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
+    if(buffer==0) {
+        result.truncate(0);
+        return result;
+    }
+
+    length=uloc_getDisplayScript(fullName, displayLocale.fullName,
+                                  buffer, result.getCapacity(),
+                                  &errorCode);
+    result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
+
+    if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
+        buffer=result.getBuffer(length);
+        if(buffer==0) {
+            result.truncate(0);
+            return result;
+        }
+        errorCode=U_ZERO_ERROR;
+        length=uloc_getDisplayScript(fullName, displayLocale.fullName,
+                                      buffer, result.getCapacity(),
+                                      &errorCode);
+        result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
+    }
+
+    return result;
+}
+
+UnicodeString&
+Locale::getDisplayCountry(UnicodeString& dispCntry) const
+{
+    return this->getDisplayCountry(getDefault(), dispCntry);
+}
+
+UnicodeString&
+Locale::getDisplayCountry(const Locale &displayLocale,
+                          UnicodeString &result) const {
+    UChar *buffer;
+    UErrorCode errorCode=U_ZERO_ERROR;
+    int32_t length;
+
+    buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
+    if(buffer==0) {
+        result.truncate(0);
+        return result;
+    }
+
+    length=uloc_getDisplayCountry(fullName, displayLocale.fullName,
+                                  buffer, result.getCapacity(),
+                                  &errorCode);
+    result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
+
+    if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
+        buffer=result.getBuffer(length);
+        if(buffer==0) {
+            result.truncate(0);
+            return result;
+        }
+        errorCode=U_ZERO_ERROR;
+        length=uloc_getDisplayCountry(fullName, displayLocale.fullName,
+                                      buffer, result.getCapacity(),
+                                      &errorCode);
+        result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
+    }
+
+    return result;
+}
+
+UnicodeString&
+Locale::getDisplayVariant(UnicodeString& dispVar) const
+{
+    return this->getDisplayVariant(getDefault(), dispVar);
+}
+
+UnicodeString&
+Locale::getDisplayVariant(const Locale &displayLocale,
+                          UnicodeString &result) const {
+    UChar *buffer;
+    UErrorCode errorCode=U_ZERO_ERROR;
+    int32_t length;
+
+    buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
+    if(buffer==0) {
+        result.truncate(0);
+        return result;
+    }
+
+    length=uloc_getDisplayVariant(fullName, displayLocale.fullName,
+                                  buffer, result.getCapacity(),
+                                  &errorCode);
+    result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
+
+    if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
+        buffer=result.getBuffer(length);
+        if(buffer==0) {
+            result.truncate(0);
+            return result;
+        }
+        errorCode=U_ZERO_ERROR;
+        length=uloc_getDisplayVariant(fullName, displayLocale.fullName,
+                                      buffer, result.getCapacity(),
+                                      &errorCode);
+        result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
+    }
+
+    return result;
+}
+
+UnicodeString&
+Locale::getDisplayName( UnicodeString& name ) const
+{
+    return this->getDisplayName(getDefault(), name);
+}
+
+UnicodeString&
+Locale::getDisplayName(const Locale &displayLocale,
+                       UnicodeString &result) const {
+    UChar *buffer;
+    UErrorCode errorCode=U_ZERO_ERROR;
+    int32_t length;
+
+    buffer=result.getBuffer(ULOC_FULLNAME_CAPACITY);
+    if(buffer==0) {
+        result.truncate(0);
+        return result;
+    }
+
+    length=uloc_getDisplayName(fullName, displayLocale.fullName,
+                               buffer, result.getCapacity(),
+                               &errorCode);
+    result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
+
+    if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
+        buffer=result.getBuffer(length);
+        if(buffer==0) {
+            result.truncate(0);
+            return result;
+        }
+        errorCode=U_ZERO_ERROR;
+        length=uloc_getDisplayName(fullName, displayLocale.fullName,
+                                   buffer, result.getCapacity(),
+                                   &errorCode);
+        result.releaseBuffer(U_SUCCESS(errorCode) ? length : 0);
+    }
+
+    return result;
+}
+
+#if ! UCONFIG_NO_BREAK_ITERATION
+
+// -------------------------------------
+// Gets the objectLocale display name in the default locale language.
+UnicodeString& U_EXPORT2
+BreakIterator::getDisplayName(const Locale& objectLocale,
+                             UnicodeString& name)
+{
+    return objectLocale.getDisplayName(name);
+}
+
+// -------------------------------------
+// Gets the objectLocale display name in the displayLocale language.
+UnicodeString& U_EXPORT2
+BreakIterator::getDisplayName(const Locale& objectLocale,
+                             const Locale& displayLocale,
+                             UnicodeString& name)
+{
+    return objectLocale.getDisplayName(displayLocale, name);
+}
+
+#endif
+
+
+U_NAMESPACE_END
+
+// C API ------------------------------------------------------------------- ***
+
+U_NAMESPACE_USE
+
+/* ### Constants **************************************************/
+
+/* These strings describe the resources we attempt to load from
+ the locale ResourceBundle data file.*/
+static const char _kLanguages[]       = "Languages";
+static const char _kScripts[]         = "Scripts";
+static const char _kCountries[]       = "Countries";
+static const char _kVariants[]        = "Variants";
+static const char _kKeys[]            = "Keys";
+static const char _kTypes[]           = "Types";
+static const char _kRootName[]        = "root";
+static const char _kCurrency[]        = "currency";
+static const char _kCurrencies[]      = "Currencies";
+static const char _kLocaleDisplayPattern[] = "localeDisplayPattern";
+static const char _kPattern[]         = "pattern";
+static const char _kSeparator[]       = "separator";
+
+/* ### Display name **************************************************/
+
+static int32_t
+_getStringOrCopyKey(const char *path, const char *locale,
+                    const char *tableKey, 
+                    const char* subTableKey,
+                    const char *itemKey,
+                    const char *substitute,
+                    UChar *dest, int32_t destCapacity,
+                    UErrorCode *pErrorCode) {
+    const UChar *s = NULL;
+    int32_t length = 0;
+
+    if(itemKey==NULL) {
+        /* top-level item: normal resource bundle access */
+        UResourceBundle *rb;
+
+        rb=ures_open(path, locale, pErrorCode);
+
+        if(U_SUCCESS(*pErrorCode)) {
+            s=ures_getStringByKey(rb, tableKey, &length, pErrorCode);
+            /* see comment about closing rb near "return item;" in _res_getTableStringWithFallback() */
+            ures_close(rb);
+        }
+    } else {
+        /* Language code should not be a number. If it is, set the error code. */
+        if (!uprv_strncmp(tableKey, "Languages", 9) && uprv_strtol(itemKey, NULL, 10)) {
+            *pErrorCode = U_MISSING_RESOURCE_ERROR;
+        } else {
+            /* second-level item, use special fallback */
+            s=uloc_getTableStringWithFallback(path, locale,
+                                               tableKey, 
+                                               subTableKey,
+                                               itemKey,
+                                               &length,
+                                               pErrorCode);
+        }
+    }
+
+    if(U_SUCCESS(*pErrorCode)) {
+        int32_t copyLength=uprv_min(length, destCapacity);
+        if(copyLength>0 && s != NULL) {
+            u_memcpy(dest, s, copyLength);
+        }
+    } else {
+        /* no string from a resource bundle: convert the substitute */
+        length=(int32_t)uprv_strlen(substitute);
+        u_charsToUChars(substitute, dest, uprv_min(length, destCapacity));
+        *pErrorCode=U_USING_DEFAULT_WARNING;
+    }
+
+    return u_terminateUChars(dest, destCapacity, length, pErrorCode);
+}
+
+typedef  int32_t U_CALLCONV UDisplayNameGetter(const char *, char *, int32_t, UErrorCode *);
+
+static int32_t
+_getDisplayNameForComponent(const char *locale,
+                            const char *displayLocale,
+                            UChar *dest, int32_t destCapacity,
+                            UDisplayNameGetter *getter,
+                            const char *tag,
+                            UErrorCode *pErrorCode) {
+    char localeBuffer[ULOC_FULLNAME_CAPACITY*4];
+    int32_t length;
+    UErrorCode localStatus;
+    const char* root = NULL;
+
+    /* argument checking */
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    if(destCapacity<0 || (destCapacity>0 && dest==NULL)) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    localStatus = U_ZERO_ERROR;
+    length=(*getter)(locale, localeBuffer, sizeof(localeBuffer), &localStatus);
+    if(U_FAILURE(localStatus) || localStatus==U_STRING_NOT_TERMINATED_WARNING) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    if(length==0) {
+        return u_terminateUChars(dest, destCapacity, 0, pErrorCode);
+    }
+
+    root = tag == _kCountries ? U_ICUDATA_REGION : U_ICUDATA_LANG;
+
+    return _getStringOrCopyKey(root, displayLocale,
+                               tag, NULL, localeBuffer,
+                               localeBuffer,
+                               dest, destCapacity,
+                               pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+uloc_getDisplayLanguage(const char *locale,
+                        const char *displayLocale,
+                        UChar *dest, int32_t destCapacity,
+                        UErrorCode *pErrorCode) {
+    return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
+                uloc_getLanguage, _kLanguages, pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+uloc_getDisplayScript(const char* locale,
+                      const char* displayLocale,
+                      UChar *dest, int32_t destCapacity,
+                      UErrorCode *pErrorCode)
+{
+    return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
+                uloc_getScript, _kScripts, pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+uloc_getDisplayCountry(const char *locale,
+                       const char *displayLocale,
+                       UChar *dest, int32_t destCapacity,
+                       UErrorCode *pErrorCode) {
+    return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
+                uloc_getCountry, _kCountries, pErrorCode);
+}
+
+/*
+ * TODO separate variant1_variant2_variant3...
+ * by getting each tag's display string and concatenating them with ", "
+ * in between - similar to uloc_getDisplayName()
+ */
+U_CAPI int32_t U_EXPORT2
+uloc_getDisplayVariant(const char *locale,
+                       const char *displayLocale,
+                       UChar *dest, int32_t destCapacity,
+                       UErrorCode *pErrorCode) {
+    return _getDisplayNameForComponent(locale, displayLocale, dest, destCapacity,
+                uloc_getVariant, _kVariants, pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+uloc_getDisplayName(const char *locale,
+                    const char *displayLocale,
+                    UChar *dest, int32_t destCapacity,
+                    UErrorCode *pErrorCode)
+{
+    int32_t length, length2, length3 = 0;
+    UBool hasLanguage, hasScript, hasCountry, hasVariant, hasKeywords;
+    UEnumeration* keywordEnum = NULL;
+    int32_t keywordCount = 0;
+    const char *keyword = NULL;
+    int32_t keywordLen = 0;
+    char keywordValue[256];
+    int32_t keywordValueLen = 0;
+
+    int32_t locSepLen = 0;
+    int32_t locPatLen = 0;
+    int32_t p0Len = 0;
+    int32_t defaultPatternLen = 9;
+    const UChar *dispLocSeparator;
+    const UChar *dispLocPattern;
+    static const UChar defaultSeparator[3] = { 0x002c, 0x0020 , 0x0000 }; /* comma + space */
+    static const UChar defaultPattern[10] = { 0x007b, 0x0030, 0x007d, 0x0020, 0x0028, 0x007b, 0x0031, 0x007d, 0x0029, 0x0000 }; /* {0} ({1}) */
+    static const UChar pat0[4] = { 0x007b, 0x0030, 0x007d , 0x0000 } ; /* {0} */
+    static const UChar pat1[4] = { 0x007b, 0x0031, 0x007d , 0x0000 } ; /* {1} */
+    
+    UResourceBundle *bundle = NULL;
+    UResourceBundle *locdsppat = NULL;
+    
+    UErrorCode status = U_ZERO_ERROR;
+
+    /* argument checking */
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    if(destCapacity<0 || (destCapacity>0 && dest==NULL)) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    bundle    = ures_open(U_ICUDATA_LANG, displayLocale, &status);
+
+    locdsppat = ures_getByKeyWithFallback(bundle, _kLocaleDisplayPattern, NULL, &status);
+    dispLocSeparator = ures_getStringByKeyWithFallback(locdsppat, _kSeparator, &locSepLen, &status);
+    dispLocPattern = ures_getStringByKeyWithFallback(locdsppat, _kPattern, &locPatLen, &status);
+        
+    /*close the bundles */
+    ures_close(locdsppat);
+    ures_close(bundle);
+
+    /* If we couldn't find any data, then use the defaults */
+    if ( locSepLen == 0) {
+       dispLocSeparator = defaultSeparator;
+       locSepLen = 2;
+    }
+
+    if ( locPatLen == 0) {
+       dispLocPattern = defaultPattern;
+       locPatLen = 9;
+    }
+
+    /*
+     * if there is a language, then write "language (country, variant)"
+     * otherwise write "country, variant"
+     */
+
+    /* write the language */
+    length=uloc_getDisplayLanguage(locale, displayLocale,
+                                   dest, destCapacity,
+                                   pErrorCode);
+    hasLanguage= length>0;
+
+    if(hasLanguage) {
+        p0Len = length;
+
+        /* append " (" */
+        if(length<destCapacity) {
+            dest[length]=0x20;
+        }
+        ++length;
+        if(length<destCapacity) {
+            dest[length]=0x28;
+        }
+        ++length;
+    }
+
+    if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
+        /* keep preflighting */
+        *pErrorCode=U_ZERO_ERROR;
+    }
+
+    /* append the script */
+    if(length<destCapacity) {
+        length2=uloc_getDisplayScript(locale, displayLocale,
+                                       dest+length, destCapacity-length,
+                                       pErrorCode);
+    } else {
+        length2=uloc_getDisplayScript(locale, displayLocale,
+                                       NULL, 0,
+                                       pErrorCode);
+    }
+    hasScript= length2>0;
+    length+=length2;
+
+    if(hasScript) {
+        /* append separator */
+        if(length+locSepLen<=destCapacity) {
+            u_memcpy(dest+length,dispLocSeparator,locSepLen);
+        }
+        length+=locSepLen;
+    }
+
+    if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
+        /* keep preflighting */
+        *pErrorCode=U_ZERO_ERROR;
+    }
+
+    /* append the country */
+    if(length<destCapacity) {
+        length2=uloc_getDisplayCountry(locale, displayLocale,
+                                       dest+length, destCapacity-length,
+                                       pErrorCode);
+    } else {
+        length2=uloc_getDisplayCountry(locale, displayLocale,
+                                       NULL, 0,
+                                       pErrorCode);
+    }
+    hasCountry= length2>0;
+    length+=length2;
+
+    if(hasCountry) {
+        /* append separator */
+        if(length+locSepLen<=destCapacity) {
+            u_memcpy(dest+length,dispLocSeparator,locSepLen);
+        }
+        length+=locSepLen;
+    }
+
+    if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
+        /* keep preflighting */
+        *pErrorCode=U_ZERO_ERROR;
+    }
+
+    /* append the variant */
+    if(length<destCapacity) {
+        length2=uloc_getDisplayVariant(locale, displayLocale,
+                                       dest+length, destCapacity-length,
+                                       pErrorCode);
+    } else {
+        length2=uloc_getDisplayVariant(locale, displayLocale,
+                                       NULL, 0,
+                                       pErrorCode);
+    }
+    hasVariant= length2>0;
+    length+=length2;
+
+    if(hasVariant) {
+        /* append separator */
+        if(length+locSepLen<=destCapacity) {
+            u_memcpy(dest+length,dispLocSeparator,locSepLen);
+        }
+        length+=locSepLen;
+    }
+
+    keywordEnum = uloc_openKeywords(locale, pErrorCode);
+    
+    for(keywordCount = uenum_count(keywordEnum, pErrorCode); keywordCount > 0 ; keywordCount--){
+          if(U_FAILURE(*pErrorCode)){
+              break;
+          }
+          /* the uenum_next returns NUL terminated string */
+          keyword = uenum_next(keywordEnum, &keywordLen, pErrorCode);
+          if(length + length3 < destCapacity) {
+            length3 += uloc_getDisplayKeyword(keyword, displayLocale, dest+length+length3, destCapacity-length-length3, pErrorCode);
+          } else {
+            length3 += uloc_getDisplayKeyword(keyword, displayLocale, NULL, 0, pErrorCode);
+          }
+          if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
+              /* keep preflighting */
+              *pErrorCode=U_ZERO_ERROR;
+          }
+          keywordValueLen = uloc_getKeywordValue(locale, keyword, keywordValue, 256, pErrorCode);
+          if(keywordValueLen) {
+            if(length + length3 < destCapacity) {
+              dest[length + length3] = 0x3D;
+            }
+            length3++;
+            if(length + length3 < destCapacity) {
+              length3 += uloc_getDisplayKeywordValue(locale, keyword, displayLocale, dest+length+length3, destCapacity-length-length3, pErrorCode);
+            } else {
+              length3 += uloc_getDisplayKeywordValue(locale, keyword, displayLocale, NULL, 0, pErrorCode);
+            }
+            if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
+                /* keep preflighting */
+                *pErrorCode=U_ZERO_ERROR;
+            }
+          }
+          if(keywordCount > 1) {
+              if(length + length3 + locSepLen <= destCapacity && keywordCount) {
+                  u_memcpy(dest+length+length3,dispLocSeparator,locSepLen);
+                  length3+=locSepLen;
+              }
+          }
+    }
+    uenum_close(keywordEnum);
+
+    hasKeywords = length3 > 0;
+    length += length3;
+
+
+    if ((hasScript && !hasCountry)
+        || ((hasScript || hasCountry) && !hasVariant && !hasKeywords)
+        || ((hasScript || hasCountry || hasVariant) && !hasKeywords)) {
+        /* Remove separator  */
+        length -= locSepLen;
+    } else if (hasLanguage && !hasScript && !hasCountry && !hasVariant && !hasKeywords) {
+        /* Remove " (" */
+        length-=2;
+    }
+
+    if (hasLanguage && (hasScript || hasCountry || hasVariant || hasKeywords)) {
+        /* append ")" */
+        if(length<destCapacity) {
+            dest[length]=0x29;
+        }
+        ++length;
+
+        /* If the localized display pattern is something other than the default pattern of "{0} ({1})", then
+         * then we need to do the formatting here.  It would be easier to use a messageFormat to do this, but we
+         * can't since we don't have the APIs in the i18n library available to us at this point.
+         */
+        if (locPatLen != defaultPatternLen || u_strcmp(dispLocPattern,defaultPattern)) { /* Something other than the default pattern */
+           UChar *p0 = u_strstr(dispLocPattern,pat0);
+           UChar *p1 = u_strstr(dispLocPattern,pat1);
+           u_terminateUChars(dest, destCapacity, length, pErrorCode);
+
+           if ( p0 != NULL && p1 != NULL ) { /* The pattern is well formed */
+              if ( dest ) {
+                  int32_t destLen = 0;
+                  UChar *result = (UChar *)uprv_malloc((length+1)*sizeof(UChar));
+                  UChar *upos = (UChar *)dispLocPattern;
+                  u_strcpy(result,dest);
+                  dest[0] = 0;
+                  while ( *upos ) {
+                     if ( upos == p0 ) { /* Handle {0} substitution */
+                         u_strncat(dest,result,p0Len);
+                         destLen += p0Len;
+                         dest[destLen] = 0; /* Null terminate */
+                         upos += 3;
+                     } else if ( upos == p1 ) { /* Handle {1} substitution */
+                         UChar *p1Start = &result[p0Len+2];
+                         u_strncat(dest,p1Start,length-p0Len-3);
+                         destLen += (length-p0Len-3);
+                         dest[destLen] = 0; /* Null terminate */
+                         upos += 3;
+                     } else { /* Something from the pattern not {0} or {1} */
+                         u_strncat(dest,upos,1);
+                         upos++;
+                         destLen++;
+                         dest[destLen] = 0; /* Null terminate */
+                     }
+                  }
+                  length = destLen;
+                  uprv_free(result);
+              }
+           }
+        }
+    }
+    if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
+        /* keep preflighting */
+        *pErrorCode=U_ZERO_ERROR;
+    }
+
+    return u_terminateUChars(dest, destCapacity, length, pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+uloc_getDisplayKeyword(const char* keyword,
+                       const char* displayLocale,
+                       UChar* dest,
+                       int32_t destCapacity,
+                       UErrorCode* status){
+
+    /* argument checking */
+    if(status==NULL || U_FAILURE(*status)) {
+        return 0;
+    }
+
+    if(destCapacity<0 || (destCapacity>0 && dest==NULL)) {
+        *status=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+
+    /* pass itemKey=NULL to look for a top-level item */
+    return _getStringOrCopyKey(U_ICUDATA_LANG, displayLocale,
+                               _kKeys, NULL, 
+                               keyword, 
+                               keyword,      
+                               dest, destCapacity,
+                               status);
+
+}
+
+
+#define UCURRENCY_DISPLAY_NAME_INDEX 1
+
+U_CAPI int32_t U_EXPORT2
+uloc_getDisplayKeywordValue(   const char* locale,
+                               const char* keyword,
+                               const char* displayLocale,
+                               UChar* dest,
+                               int32_t destCapacity,
+                               UErrorCode* status){
+
+
+    char keywordValue[ULOC_FULLNAME_CAPACITY*4];
+    int32_t capacity = ULOC_FULLNAME_CAPACITY*4;
+    int32_t keywordValueLen =0;
+
+    /* argument checking */
+    if(status==NULL || U_FAILURE(*status)) {
+        return 0;
+    }
+
+    if(destCapacity<0 || (destCapacity>0 && dest==NULL)) {
+        *status=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    /* get the keyword value */
+    keywordValue[0]=0;
+    keywordValueLen = uloc_getKeywordValue(locale, keyword, keywordValue, capacity, status);
+
+    /* 
+     * if the keyword is equal to currency .. then to get the display name 
+     * we need to do the fallback ourselves
+     */
+    if(uprv_stricmp(keyword, _kCurrency)==0){
+
+        int32_t dispNameLen = 0;
+        const UChar *dispName = NULL;
+        
+        UResourceBundle *bundle     = ures_open(U_ICUDATA_CURR, displayLocale, status);
+        UResourceBundle *currencies = ures_getByKey(bundle, _kCurrencies, NULL, status);
+        UResourceBundle *currency   = ures_getByKeyWithFallback(currencies, keywordValue, NULL, status);
+        
+        dispName = ures_getStringByIndex(currency, UCURRENCY_DISPLAY_NAME_INDEX, &dispNameLen, status);
+        
+        /*close the bundles */
+        ures_close(currency);
+        ures_close(currencies);
+        ures_close(bundle);
+        
+        if(U_FAILURE(*status)){
+            if(*status == U_MISSING_RESOURCE_ERROR){
+                /* we just want to write the value over if nothing is available */
+                *status = U_USING_DEFAULT_WARNING;
+            }else{
+                return 0;
+            }
+        }
+
+        /* now copy the dispName over if not NULL */
+        if(dispName != NULL){
+            if(dispNameLen <= destCapacity){
+                uprv_memcpy(dest, dispName, dispNameLen * U_SIZEOF_UCHAR);
+                return u_terminateUChars(dest, destCapacity, dispNameLen, status);
+            }else{
+                *status = U_BUFFER_OVERFLOW_ERROR;
+                return dispNameLen;
+            }
+        }else{
+            /* we have not found the display name for the value .. just copy over */
+            if(keywordValueLen <= destCapacity){
+                u_charsToUChars(keywordValue, dest, keywordValueLen);
+                return u_terminateUChars(dest, destCapacity, keywordValueLen, status);
+            }else{
+                 *status = U_BUFFER_OVERFLOW_ERROR;
+                return keywordValueLen;
+            }
+        }
+
+        
+    }else{
+
+        return _getStringOrCopyKey(U_ICUDATA_LANG, displayLocale,
+                                   _kTypes, keyword, 
+                                   keywordValue,
+                                   keywordValue,
+                                   dest, destCapacity,
+                                   status);
+    }
+}
diff --git a/icu/source/common/locid.cpp b/icu/source/common/locid.cpp
new file mode 100644
index 0000000..e87b8b3
--- /dev/null
+++ b/icu/source/common/locid.cpp
@@ -0,0 +1,1101 @@
+/*
+ **********************************************************************
+ *   Copyright (C) 1997-2010, International Business Machines
+ *   Corporation and others.  All Rights Reserved.
+ **********************************************************************
+*
+* File locid.cpp
+*
+* Created by: Richard Gillam
+*
+* Modification History:
+*
+*   Date        Name        Description
+*   02/11/97    aliu        Changed gLocPath to fgDataDirectory and added
+*                           methods to get and set it.
+*   04/02/97    aliu        Made operator!= inline; fixed return value
+*                           of getName().
+*   04/15/97    aliu        Cleanup for AIX/Win32.
+*   04/24/97    aliu        Numerous changes per code review.
+*   08/18/98    stephen     Changed getDisplayName()
+*                           Added SIMPLIFIED_CHINESE, TRADITIONAL_CHINESE
+*                           Added getISOCountries(), getISOLanguages(),
+*                           getLanguagesForCountry()
+*   03/16/99    bertrand    rehaul.
+*   07/21/99    stephen     Added U_CFUNC setDefault
+*   11/09/99    weiv        Added const char * getName() const;
+*   04/12/00    srl         removing unicodestring api's and cached hash code
+*   08/10/01    grhoten     Change the static Locales to accessor functions
+******************************************************************************
+*/
+
+
+#include "unicode/locid.h"
+#include "unicode/uloc.h"
+#include "umutex.h"
+#include "uassert.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "uhash.h"
+#include "ucln_cmn.h"
+
+#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
+
+typedef enum ELocalePos {
+    eENGLISH,
+    eFRENCH,
+    eGERMAN,
+    eITALIAN,
+    eJAPANESE,
+    eKOREAN,
+    eCHINESE,
+
+    eFRANCE,
+    eGERMANY,
+    eITALY,
+    eJAPAN,
+    eKOREA,
+    eCHINA,      /* Alias for PRC */
+    eTAIWAN,
+    eUK,
+    eUS,
+    eCANADA,
+    eCANADA_FRENCH,
+    eROOT,
+
+
+    //eDEFAULT,
+    eMAX_LOCALES
+} ELocalePos;
+
+U_CFUNC int32_t locale_getKeywords(const char *localeID,
+            char prev,
+            char *keywords, int32_t keywordCapacity,
+            char *values, int32_t valuesCapacity, int32_t *valLen,
+            UBool valuesToo,
+            UErrorCode *status);
+
+static U_NAMESPACE_QUALIFIER Locale *gLocaleCache         = NULL;
+static U_NAMESPACE_QUALIFIER Locale *gDefaultLocale       = NULL;
+static UHashtable                   *gDefaultLocalesHashT = NULL;
+
+U_CDECL_BEGIN
+//
+// Deleter function for Locales owned by the default Locale hash table/
+//
+static void U_CALLCONV
+deleteLocale(void *obj) {
+    delete (U_NAMESPACE_QUALIFIER Locale *) obj;
+}
+
+static UBool U_CALLCONV locale_cleanup(void)
+{
+    U_NAMESPACE_USE
+
+    if (gLocaleCache) {
+        delete [] gLocaleCache;
+        gLocaleCache = NULL;
+    }
+
+    if (gDefaultLocalesHashT) {
+        uhash_close(gDefaultLocalesHashT);   // Automatically deletes all elements, using deleter func.
+        gDefaultLocalesHashT = NULL;
+    }
+    else if (gDefaultLocale) {
+        // The cache wasn't created, and only one default locale was created.
+        delete gDefaultLocale;
+    }
+    gDefaultLocale = NULL;
+
+    return TRUE;
+}
+U_CDECL_END
+
+U_NAMESPACE_BEGIN
+//
+//  locale_set_default_internal.
+//
+void locale_set_default_internal(const char *id)
+{
+    UErrorCode   status = U_ZERO_ERROR;
+    UBool canonicalize = FALSE;
+
+    // If given a NULL string for the locale id, grab the default
+    //   name from the system.
+    //   (Different from most other locale APIs, where a null name means use
+    //    the current ICU default locale.)
+    if (id == NULL) {
+        umtx_lock(NULL);
+        id = uprv_getDefaultLocaleID();
+        umtx_unlock(NULL);
+        canonicalize = TRUE; // always canonicalize host ID
+    }
+
+    // put the locale id into a canonical form,
+    //   in preparation for looking up this locale in the hash table of
+    //   already-created locale objects.
+    //
+    status = U_ZERO_ERROR;
+    char localeNameBuf[512];
+
+    if (canonicalize) {
+        uloc_canonicalize(id, localeNameBuf, sizeof(localeNameBuf)-1, &status);
+    } else {
+        uloc_getName(id, localeNameBuf, sizeof(localeNameBuf)-1, &status);
+    }
+    localeNameBuf[sizeof(localeNameBuf)-1] = 0;  // Force null termination in event of
+                                                 //   a long name filling the buffer.
+                                                 //   (long names are truncated.)
+
+    // Lazy creation of the hash table itself, if needed.
+    UBool isOnlyLocale;
+    UMTX_CHECK(NULL, (gDefaultLocale == NULL), isOnlyLocale);
+    if (isOnlyLocale) {
+        // We haven't seen this locale id before.
+        // Create a new Locale object for it.
+        Locale *newFirstDefault = new Locale(Locale::eBOGUS);
+        if (newFirstDefault == NULL) {
+            // No way to report errors from here.
+            return;
+        }
+        newFirstDefault->init(localeNameBuf, FALSE);
+        umtx_lock(NULL);
+        if (gDefaultLocale == NULL) {
+            gDefaultLocale = newFirstDefault;  // Assignment to gDefaultLocale must happen inside mutex
+            newFirstDefault = NULL;
+            ucln_common_registerCleanup(UCLN_COMMON_LOCALE, locale_cleanup);
+        }
+        // Else some other thread raced us through here, and set the new Locale.
+        // Use the hash table next.
+        umtx_unlock(NULL);
+        if (newFirstDefault == NULL) {
+            // We were successful in setting the locale, and we were the first one to set it.
+            return;
+        }
+        // else start using the hash table.
+    }
+
+    // Lazy creation of the hash table itself, if needed.
+    UBool hashTableNeedsInit;
+    UMTX_CHECK(NULL, (gDefaultLocalesHashT == NULL), hashTableNeedsInit);
+    if (hashTableNeedsInit) {
+        status = U_ZERO_ERROR;
+        UHashtable *tHashTable = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &status);
+        if (U_FAILURE(status)) {
+            return;
+        }
+        uhash_setValueDeleter(tHashTable, deleteLocale);
+        umtx_lock(NULL);
+        if (gDefaultLocalesHashT == NULL) {
+            gDefaultLocalesHashT = tHashTable;
+            ucln_common_registerCleanup(UCLN_COMMON_LOCALE, locale_cleanup);
+        } else {
+            uhash_close(tHashTable);
+            hashTableNeedsInit = FALSE;
+        }
+        umtx_unlock(NULL);
+    }
+
+    // Hash table lookup, key is the locale full name
+    umtx_lock(NULL);
+    Locale *newDefault = (Locale *)uhash_get(gDefaultLocalesHashT, localeNameBuf);
+    if (newDefault != NULL) {
+        // We have the requested locale in the hash table already.
+        // Just set it as default.  Inside the mutex lock, for those troublesome processors.
+        gDefaultLocale = newDefault;
+        umtx_unlock(NULL);
+    } else {
+        umtx_unlock(NULL);
+        // We haven't seen this locale id before.
+        // Create a new Locale object for it.
+        newDefault = new Locale(Locale::eBOGUS);
+        if (newDefault == NULL) {
+            // No way to report errors from here.
+            return;
+        }
+        newDefault->init(localeNameBuf, FALSE);
+
+        // Add newly created Locale to the hash table of default Locales
+        const char *key = newDefault->getName();
+        U_ASSERT(uprv_strcmp(key, localeNameBuf) == 0);
+        umtx_lock(NULL);
+        Locale *hashTableVal = (Locale *)uhash_get(gDefaultLocalesHashT, key);
+        if (hashTableVal == NULL) {
+            if (hashTableNeedsInit) {
+                // This is the second request to set the locale.
+                // Cache the first one.
+                uhash_put(gDefaultLocalesHashT, (void *)gDefaultLocale->getName(), gDefaultLocale, &status);
+            }
+            uhash_put(gDefaultLocalesHashT, (void *)key, newDefault, &status);
+            gDefaultLocale = newDefault;
+            // ignore errors from hash table insert.  (Couldn't do anything anyway)
+            // We can still set the default Locale,
+            //  it just wont be cached, and will eventually leak.
+        } else {
+            // Some other thread raced us through here, and got the new Locale
+            //   into the hash table before us.  Use that one.
+            gDefaultLocale = hashTableVal;  // Assignment to gDefaultLocale must happen inside mutex
+            delete newDefault;
+        }
+        umtx_unlock(NULL);
+    }
+}
+U_NAMESPACE_END
+
+/* sfb 07/21/99 */
+U_CFUNC void
+locale_set_default(const char *id)
+{
+    U_NAMESPACE_USE
+    locale_set_default_internal(id);
+}
+/* end */
+
+U_CFUNC const char *
+locale_get_default(void)
+{
+    U_NAMESPACE_USE
+
+    return Locale::getDefault().getName();
+}
+
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Locale)
+
+/*Character separating the posix id fields*/
+// '_'
+// In the platform codepage.
+#define SEP_CHAR '_'
+
+Locale::~Locale()
+{
+    /*if fullName is on the heap, we free it*/
+    if (fullName != fullNameBuffer)
+    {
+        uprv_free(fullName);
+        fullName = NULL;
+    }
+    if (baseName && baseName != baseNameBuffer) {
+        uprv_free(baseName);
+        baseName = NULL;
+    }
+}
+
+Locale::Locale()
+    : UObject(), fullName(fullNameBuffer), baseName(NULL)
+{
+    init(NULL, FALSE);
+}
+
+/*
+ * Internal constructor to allow construction of a locale object with
+ *   NO side effects.   (Default constructor tries to get
+ *   the default locale.)
+ */
+Locale::Locale(Locale::ELocaleType)
+    : UObject(), fullName(fullNameBuffer), baseName(NULL)
+{
+    setToBogus();
+}
+
+
+Locale::Locale( const   char * newLanguage,
+                const   char * newCountry,
+                const   char * newVariant,
+                const   char * newKeywords)
+    : UObject(), fullName(fullNameBuffer), baseName(NULL)
+{
+    if( (newLanguage==NULL) && (newCountry == NULL) && (newVariant == NULL) )
+    {
+        init(NULL, FALSE); /* shortcut */
+    }
+    else
+    {
+        MaybeStackArray<char, ULOC_FULLNAME_CAPACITY> togo;
+        int32_t size = 0;
+        int32_t lsize = 0;
+        int32_t csize = 0;
+        int32_t vsize = 0;
+        int32_t ksize = 0;
+        char    *p;
+
+        // Calculate the size of the resulting string.
+
+        // Language
+        if ( newLanguage != NULL )
+        {
+            lsize = (int32_t)uprv_strlen(newLanguage);
+            size = lsize;
+        }
+
+        // _Country
+        if ( newCountry != NULL )
+        {
+            csize = (int32_t)uprv_strlen(newCountry);
+            size += csize;
+        }
+
+        // _Variant
+        if ( newVariant != NULL )
+        {
+            // remove leading _'s
+            while(newVariant[0] == SEP_CHAR)
+            {
+                newVariant++;
+            }
+
+            // remove trailing _'s
+            vsize = (int32_t)uprv_strlen(newVariant);
+            while( (vsize>1) && (newVariant[vsize-1] == SEP_CHAR) )
+            {
+                vsize--;
+            }
+        }
+
+        if( vsize > 0 )
+        {
+            size += vsize;
+        }
+
+        // Separator rules:
+        if ( vsize > 0 )
+        {
+            size += 2;  // at least: __v
+        }
+        else if ( csize > 0 )
+        {
+            size += 1;  // at least: _v
+        }
+
+        if ( newKeywords != NULL)
+        {
+            ksize = (int32_t)uprv_strlen(newKeywords);
+            size += ksize + 1;
+        }
+
+
+        //  NOW we have the full locale string..
+
+        /*if the whole string is longer than our internal limit, we need
+        to go to the heap for temporary buffers*/
+        if (size >= togo.getCapacity())
+        {
+            // If togo_heap could not be created, initialize with default settings.
+            if (togo.resize(size+1) == NULL) {
+                init(NULL, FALSE);
+            }
+        }
+
+        togo[0] = 0;
+
+        // Now, copy it back.
+        p = togo.getAlias();
+        if ( lsize != 0 )
+        {
+            uprv_strcpy(p, newLanguage);
+            p += lsize;
+        }
+
+        if ( ( vsize != 0 ) || (csize != 0) )  // at least:  __v
+        {                                      //            ^
+            *p++ = SEP_CHAR;
+        }
+
+        if ( csize != 0 )
+        {
+            uprv_strcpy(p, newCountry);
+            p += csize;
+        }
+
+        if ( vsize != 0)
+        {
+            *p++ = SEP_CHAR; // at least: __v
+
+            uprv_strncpy(p, newVariant, vsize);  // Must use strncpy because
+            p += vsize;                          // of trimming (above).
+            *p = 0; // terminate
+        }
+
+        if ( ksize != 0)
+        {
+            if (uprv_strchr(newKeywords, '=')) {
+                *p++ = '@'; /* keyword parsing */
+            }
+            else {
+                *p++ = '_'; /* Variant parsing with a script */
+                if ( vsize == 0) {
+                    *p++ = '_'; /* No country found */
+                }
+            }
+            uprv_strcpy(p, newKeywords);
+            p += ksize;
+        }
+
+        // Parse it, because for example 'language' might really be a complete
+        // string.
+        init(togo.getAlias(), FALSE);
+    }
+}
+
+Locale::Locale(const Locale &other)
+    : UObject(other), fullName(fullNameBuffer), baseName(NULL)
+{
+    *this = other;
+}
+
+Locale &Locale::operator=(const Locale &other)
+{
+    if (this == &other) {
+        return *this;
+    }
+
+    if (&other == NULL) {
+        this->setToBogus();
+        return *this;
+    }
+
+    /* Free our current storage */
+    if(fullName != fullNameBuffer) {
+        uprv_free(fullName);
+        fullName = fullNameBuffer;
+    }
+
+    /* Allocate the full name if necessary */
+    if(other.fullName != other.fullNameBuffer) {
+        fullName = (char *)uprv_malloc(sizeof(char)*(uprv_strlen(other.fullName)+1));
+        if (fullName == NULL) {
+            return *this;
+        }
+    }
+    /* Copy the full name */
+    uprv_strcpy(fullName, other.fullName);
+
+    /* baseName is the cached result of getBaseName.  if 'other' has a
+       baseName and it fits in baseNameBuffer, then copy it. otherwise set
+       it to NULL, and let the user lazy-create it (in getBaseName) if they
+       want it. */
+    if(baseName && baseName != baseNameBuffer) {
+        uprv_free(baseName);
+    }
+    baseName = NULL;
+
+    if(other.baseName == other.baseNameBuffer) {
+        uprv_strcpy(baseNameBuffer, other.baseNameBuffer);
+        baseName = baseNameBuffer;
+    }
+
+    /* Copy the language and country fields */
+    uprv_strcpy(language, other.language);
+    uprv_strcpy(script, other.script);
+    uprv_strcpy(country, other.country);
+
+    /* The variantBegin is an offset, just copy it */
+    variantBegin = other.variantBegin;
+    fIsBogus = other.fIsBogus;
+    return *this;
+}
+
+Locale *
+Locale::clone() const {
+    return new Locale(*this);
+}
+
+UBool
+Locale::operator==( const   Locale& other) const
+{
+    return (uprv_strcmp(other.fullName, fullName) == 0);
+}
+
+/*This function initializes a Locale from a C locale ID*/
+Locale& Locale::init(const char* localeID, UBool canonicalize)
+{
+    fIsBogus = FALSE;
+    /* Free our current storage */
+    if(fullName != fullNameBuffer) {
+        uprv_free(fullName);
+        fullName = fullNameBuffer;
+    }
+
+    if(baseName && baseName != baseNameBuffer) {
+        uprv_free(baseName);
+        baseName = NULL;
+    }
+
+    // not a loop:
+    // just an easy way to have a common error-exit
+    // without goto and without another function
+    do {
+        char *separator;
+        char *field[5] = {0};
+        int32_t fieldLen[5] = {0};
+        int32_t fieldIdx;
+        int32_t variantField;
+        int32_t length;
+        UErrorCode err;
+
+        if(localeID == NULL) {
+            // not an error, just set the default locale
+            return *this = getDefault();
+        }
+
+        /* preset all fields to empty */
+        language[0] = script[0] = country[0] = 0;
+
+        // "canonicalize" the locale ID to ICU/Java format
+        err = U_ZERO_ERROR;
+        length = canonicalize ?
+            uloc_canonicalize(localeID, fullName, sizeof(fullNameBuffer), &err) :
+            uloc_getName(localeID, fullName, sizeof(fullNameBuffer), &err);
+
+        if(err == U_BUFFER_OVERFLOW_ERROR || length >= (int32_t)sizeof(fullNameBuffer)) {
+            /*Go to heap for the fullName if necessary*/
+            fullName = (char *)uprv_malloc(sizeof(char)*(length + 1));
+            if(fullName == 0) {
+                fullName = fullNameBuffer;
+                break; // error: out of memory
+            }
+            err = U_ZERO_ERROR;
+            length = canonicalize ?
+                uloc_canonicalize(localeID, fullName, length+1, &err) :
+                uloc_getName(localeID, fullName, length+1, &err);
+        }
+        if(U_FAILURE(err) || err == U_STRING_NOT_TERMINATED_WARNING) {
+            /* should never occur */
+            break;
+        }
+
+        variantBegin = length;
+
+        /* after uloc_getName/canonicalize() we know that only '_' are separators */
+        separator = field[0] = fullName;
+        fieldIdx = 1;
+        while ((separator = uprv_strchr(field[fieldIdx-1], SEP_CHAR)) && fieldIdx < (int32_t)(sizeof(field)/sizeof(field[0]))-1) {
+            field[fieldIdx] = separator + 1;
+            fieldLen[fieldIdx-1] = (int32_t)(separator - field[fieldIdx-1]);
+            fieldIdx++;
+        }
+        // variant may contain @foo or .foo POSIX cruft; remove it
+        separator = uprv_strchr(field[fieldIdx-1], '@');
+        char* sep2 = uprv_strchr(field[fieldIdx-1], '.');
+        if (separator!=NULL || sep2!=NULL) {
+            if (separator==NULL || (sep2!=NULL && separator > sep2)) {
+                separator = sep2;
+            }
+            fieldLen[fieldIdx-1] = (int32_t)(separator - field[fieldIdx-1]);
+        } else {
+            fieldLen[fieldIdx-1] = length - (int32_t)(field[fieldIdx-1] - fullName);
+        }
+
+        if (fieldLen[0] >= (int32_t)(sizeof(language))
+            || (fieldLen[1] == 4 && fieldLen[2] >= (int32_t)(sizeof(country)))
+            || (fieldLen[1] != 4 && fieldLen[1] >= (int32_t)(sizeof(country))))
+        {
+            break; // error: one of the fields is too long
+        }
+
+        variantField = 2; /* Usually the 2nd one, except when a script is used. */
+        if (fieldLen[0] > 0) {
+            /* We have a language */
+            uprv_memcpy(language, fullName, fieldLen[0]);
+            language[fieldLen[0]] = 0;
+        }
+        if (fieldLen[1] == 4) {
+            /* We have at least a script */
+            uprv_memcpy(script, field[1], fieldLen[1]);
+            script[fieldLen[1]] = 0;
+            variantField = 3;
+            if (fieldLen[2] > 0) {
+                /* We have a country */
+                uprv_memcpy(country, field[2], fieldLen[2]);
+                country[fieldLen[2]] = 0;
+            }
+        }
+        else if (fieldLen[1] > 0) {
+            /* We have a country and no script */
+            uprv_memcpy(country, field[1], fieldLen[1]);
+            country[fieldLen[1]] = 0;
+        }
+        if (variantField > 0 && fieldLen[variantField] > 0) {
+            /* We have a variant */
+            variantBegin = (int32_t)(field[variantField] - fullName);
+        }
+
+        // successful end of init()
+        return *this;
+    } while(0); /*loop doesn't iterate*/
+
+    // when an error occurs, then set this object to "bogus" (there is no UErrorCode here)
+    setToBogus();
+
+    return *this;
+}
+
+int32_t
+Locale::hashCode() const
+{
+    UHashTok hashKey;
+    hashKey.pointer = fullName;
+    return uhash_hashChars(hashKey);
+}
+
+void
+Locale::setToBogus() {
+    /* Free our current storage */
+    if(fullName != fullNameBuffer) {
+        uprv_free(fullName);
+        fullName = fullNameBuffer;
+    }
+    if(baseName && baseName != baseNameBuffer) {
+        uprv_free(baseName);
+        baseName = NULL;
+    }
+    *fullNameBuffer = 0;
+    *language = 0;
+    *script = 0;
+    *country = 0;
+    fIsBogus = TRUE;
+}
+
+const Locale& U_EXPORT2
+Locale::getDefault()
+{
+    const Locale *retLocale;
+    UMTX_CHECK(NULL, gDefaultLocale, retLocale);
+    if (retLocale == NULL) {
+        locale_set_default_internal(NULL);
+        umtx_lock(NULL);
+        // Need a mutex  in case some other thread set a new
+        // default inbetween when we set and when we get the new default.  For
+        // processors with weak memory coherency, we might not otherwise see all
+        // of the newly created new default locale.
+        retLocale = gDefaultLocale;
+        umtx_unlock(NULL);
+    }
+    return *retLocale;
+}
+
+
+
+void U_EXPORT2
+Locale::setDefault( const   Locale&     newLocale,
+                            UErrorCode&  status)
+{
+    if (U_FAILURE(status)) {
+        return;
+    }
+
+    /* Set the default from the full name string of the supplied locale.
+     * This is a convenient way to access the default locale caching mechanisms.
+     */
+    const char *localeID = newLocale.getName();
+    locale_set_default_internal(localeID);
+}
+
+Locale U_EXPORT2
+Locale::createFromName (const char *name)
+{
+    if (name) {
+        Locale l("");
+        l.init(name, FALSE);
+        return l;
+    }
+    else {
+        return getDefault();
+    }
+}
+
+Locale U_EXPORT2
+Locale::createCanonical(const char* name) {
+    Locale loc("");
+    loc.init(name, TRUE);
+    return loc;
+}
+
+const char *
+Locale::getISO3Language() const
+{
+    return uloc_getISO3Language(fullName);
+}
+
+
+const char *
+Locale::getISO3Country() const
+{
+    return uloc_getISO3Country(fullName);
+}
+
+/**
+ * Return the LCID value as specified in the "LocaleID" resource for this
+ * locale.  The LocaleID must be expressed as a hexadecimal number, from
+ * one to four digits.  If the LocaleID resource is not present, or is
+ * in an incorrect format, 0 is returned.  The LocaleID is for use in
+ * Windows (it is an LCID), but is available on all platforms.
+ */
+uint32_t
+Locale::getLCID() const
+{
+    return uloc_getLCID(fullName);
+}
+
+const char* const* U_EXPORT2 Locale::getISOCountries()
+{
+    return uloc_getISOCountries();
+}
+
+const char* const* U_EXPORT2 Locale::getISOLanguages()
+{
+    return uloc_getISOLanguages();
+}
+
+// Set the locale's data based on a posix id.
+void Locale::setFromPOSIXID(const char *posixID)
+{
+    init(posixID, TRUE);
+}
+
+const Locale & U_EXPORT2
+Locale::getRoot(void)
+{
+    return getLocale(eROOT);
+}
+
+const Locale & U_EXPORT2
+Locale::getEnglish(void)
+{
+    return getLocale(eENGLISH);
+}
+
+const Locale & U_EXPORT2
+Locale::getFrench(void)
+{
+    return getLocale(eFRENCH);
+}
+
+const Locale & U_EXPORT2
+Locale::getGerman(void)
+{
+    return getLocale(eGERMAN);
+}
+
+const Locale & U_EXPORT2
+Locale::getItalian(void)
+{
+    return getLocale(eITALIAN);
+}
+
+const Locale & U_EXPORT2
+Locale::getJapanese(void)
+{
+    return getLocale(eJAPANESE);
+}
+
+const Locale & U_EXPORT2
+Locale::getKorean(void)
+{
+    return getLocale(eKOREAN);
+}
+
+const Locale & U_EXPORT2
+Locale::getChinese(void)
+{
+    return getLocale(eCHINESE);
+}
+
+const Locale & U_EXPORT2
+Locale::getSimplifiedChinese(void)
+{
+    return getLocale(eCHINA);
+}
+
+const Locale & U_EXPORT2
+Locale::getTraditionalChinese(void)
+{
+    return getLocale(eTAIWAN);
+}
+
+
+const Locale & U_EXPORT2
+Locale::getFrance(void)
+{
+    return getLocale(eFRANCE);
+}
+
+const Locale & U_EXPORT2
+Locale::getGermany(void)
+{
+    return getLocale(eGERMANY);
+}
+
+const Locale & U_EXPORT2
+Locale::getItaly(void)
+{
+    return getLocale(eITALY);
+}
+
+const Locale & U_EXPORT2
+Locale::getJapan(void)
+{
+    return getLocale(eJAPAN);
+}
+
+const Locale & U_EXPORT2
+Locale::getKorea(void)
+{
+    return getLocale(eKOREA);
+}
+
+const Locale & U_EXPORT2
+Locale::getChina(void)
+{
+    return getLocale(eCHINA);
+}
+
+const Locale & U_EXPORT2
+Locale::getPRC(void)
+{
+    return getLocale(eCHINA);
+}
+
+const Locale & U_EXPORT2
+Locale::getTaiwan(void)
+{
+    return getLocale(eTAIWAN);
+}
+
+const Locale & U_EXPORT2
+Locale::getUK(void)
+{
+    return getLocale(eUK);
+}
+
+const Locale & U_EXPORT2
+Locale::getUS(void)
+{
+    return getLocale(eUS);
+}
+
+const Locale & U_EXPORT2
+Locale::getCanada(void)
+{
+    return getLocale(eCANADA);
+}
+
+const Locale & U_EXPORT2
+Locale::getCanadaFrench(void)
+{
+    return getLocale(eCANADA_FRENCH);
+}
+
+const Locale &
+Locale::getLocale(int locid)
+{
+    Locale *localeCache = getLocaleCache();
+    U_ASSERT((locid < eMAX_LOCALES)&&(locid>=0));
+    if (localeCache == NULL) {
+        // Failure allocating the locale cache.
+        //   The best we can do is return a NULL reference.
+        locid = 0;
+    }
+    return localeCache[locid]; /*operating on NULL*/
+}
+
+/*
+This function is defined this way in order to get around static
+initialization and static destruction.
+ */
+Locale *
+Locale::getLocaleCache(void)
+{
+    umtx_lock(NULL);
+    UBool needInit = (gLocaleCache == NULL);
+    umtx_unlock(NULL);
+
+    if (needInit) {
+        Locale *tLocaleCache = new Locale[(int)eMAX_LOCALES];
+        if (tLocaleCache == NULL) {
+            return NULL;
+        }
+	tLocaleCache[eROOT]          = Locale("");
+        tLocaleCache[eENGLISH]       = Locale("en");
+        tLocaleCache[eFRENCH]        = Locale("fr");
+        tLocaleCache[eGERMAN]        = Locale("de");
+        tLocaleCache[eITALIAN]       = Locale("it");
+        tLocaleCache[eJAPANESE]      = Locale("ja");
+        tLocaleCache[eKOREAN]        = Locale("ko");
+        tLocaleCache[eCHINESE]       = Locale("zh");
+        tLocaleCache[eFRANCE]        = Locale("fr", "FR");
+        tLocaleCache[eGERMANY]       = Locale("de", "DE");
+        tLocaleCache[eITALY]         = Locale("it", "IT");
+        tLocaleCache[eJAPAN]         = Locale("ja", "JP");
+        tLocaleCache[eKOREA]         = Locale("ko", "KR");
+        tLocaleCache[eCHINA]         = Locale("zh", "CN");
+        tLocaleCache[eTAIWAN]        = Locale("zh", "TW");
+        tLocaleCache[eUK]            = Locale("en", "GB");
+        tLocaleCache[eUS]            = Locale("en", "US");
+        tLocaleCache[eCANADA]        = Locale("en", "CA");
+        tLocaleCache[eCANADA_FRENCH] = Locale("fr", "CA");
+
+        umtx_lock(NULL);
+        if (gLocaleCache == NULL) {
+            gLocaleCache = tLocaleCache;
+            tLocaleCache = NULL;
+            ucln_common_registerCleanup(UCLN_COMMON_LOCALE, locale_cleanup);
+        }
+        umtx_unlock(NULL);
+        if (tLocaleCache) {
+            delete [] tLocaleCache;  // Fancy array delete will destruct each member.
+        }
+    }
+    return gLocaleCache;
+}
+
+class KeywordEnumeration : public StringEnumeration {
+private:
+    char *keywords;
+    char *current;
+    int32_t length;
+    UnicodeString currUSKey;
+    static const char fgClassID;/* Warning this is used beyond the typical RTTI usage. */
+
+public:
+    static UClassID U_EXPORT2 getStaticClassID(void) { return (UClassID)&fgClassID; }
+    virtual UClassID getDynamicClassID(void) const { return getStaticClassID(); }
+public:
+    KeywordEnumeration(const char *keys, int32_t keywordLen, int32_t currentIndex, UErrorCode &status)
+        : keywords((char *)&fgClassID), current((char *)&fgClassID), length(0) {
+        if(U_SUCCESS(status) && keywordLen != 0) {
+            if(keys == NULL || keywordLen < 0) {
+                status = U_ILLEGAL_ARGUMENT_ERROR;
+            } else {
+                keywords = (char *)uprv_malloc(keywordLen+1);
+                if (keywords == NULL) {
+                    status = U_MEMORY_ALLOCATION_ERROR;
+                }
+                else {
+                    uprv_memcpy(keywords, keys, keywordLen);
+                    keywords[keywordLen] = 0;
+                    current = keywords + currentIndex;
+                    length = keywordLen;
+                }
+            }
+        }
+    }
+
+    virtual ~KeywordEnumeration() {
+        uprv_free(keywords);
+    }
+
+    virtual StringEnumeration * clone() const
+    {
+        UErrorCode status = U_ZERO_ERROR;
+        return new KeywordEnumeration(keywords, length, (int32_t)(current - keywords), status);
+    }
+
+    virtual int32_t count(UErrorCode &/*status*/) const {
+        char *kw = keywords;
+        int32_t result = 0;
+        while(*kw) {
+            result++;
+            kw += uprv_strlen(kw)+1;
+        }
+        return result;
+    }
+
+    virtual const char* next(int32_t* resultLength, UErrorCode& status) {
+        const char* result;
+        int32_t len;
+        if(U_SUCCESS(status) && *current != 0) {
+            result = current;
+            len = (int32_t)uprv_strlen(current);
+            current += len+1;
+            if(resultLength != NULL) {
+                *resultLength = len;
+            }
+        } else {
+            if(resultLength != NULL) {
+                *resultLength = 0;
+            }
+            result = NULL;
+        }
+        return result;
+    }
+
+    virtual const UnicodeString* snext(UErrorCode& status) {
+        int32_t resultLength = 0;
+        const char *s = next(&resultLength, status);
+        return setChars(s, resultLength, status);
+    }
+
+    virtual void reset(UErrorCode& /*status*/) {
+        current = keywords;
+    }
+};
+
+const char KeywordEnumeration::fgClassID = '\0';
+
+StringEnumeration *
+Locale::createKeywords(UErrorCode &status) const
+{
+    char keywords[256];
+    int32_t keywordCapacity = 256;
+    StringEnumeration *result = NULL;
+
+    const char* variantStart = uprv_strchr(fullName, '@');
+    const char* assignment = uprv_strchr(fullName, '=');
+    if(variantStart) {
+        if(assignment > variantStart) {
+            int32_t keyLen = locale_getKeywords(variantStart+1, '@', keywords, keywordCapacity, NULL, 0, NULL, FALSE, &status);
+            if(keyLen) {
+                result = new KeywordEnumeration(keywords, keyLen, 0, status);
+            }
+        } else {
+            status = U_INVALID_FORMAT_ERROR;
+        }
+    }
+    return result;
+}
+
+int32_t
+Locale::getKeywordValue(const char* keywordName, char *buffer, int32_t bufLen, UErrorCode &status) const
+{
+    return uloc_getKeywordValue(fullName, keywordName, buffer, bufLen, &status);
+}
+
+void
+Locale::setKeywordValue(const char* keywordName, const char* keywordValue, UErrorCode &status)
+{
+    uloc_setKeywordValue(keywordName, keywordValue, fullName, ULOC_FULLNAME_CAPACITY, &status);
+}
+
+const char *
+Locale::getBaseName() const
+{
+    // lazy init
+    UErrorCode status = U_ZERO_ERROR;
+    // semantically const
+    if(baseName == 0) {
+        ((Locale *)this)->baseName = ((Locale *)this)->baseNameBuffer;
+        int32_t baseNameSize = uloc_getBaseName(fullName, baseName, ULOC_FULLNAME_CAPACITY, &status);
+        if(baseNameSize >= ULOC_FULLNAME_CAPACITY) {
+            ((Locale *)this)->baseName = (char *)uprv_malloc(sizeof(char) * baseNameSize + 1);
+            if (baseName == NULL) {
+                return baseName;
+            }
+            uloc_getBaseName(fullName, baseName, baseNameSize+1, &status);
+        }
+        baseName[baseNameSize] = 0;
+
+        // the computation of variantBegin leaves it equal to the length
+        // of fullName if there is no variant.  It should instead be
+        // the length of the baseName.  Patch around this for now.
+        if (variantBegin == uprv_strlen(fullName)) {
+          ((Locale*)this)->variantBegin = baseNameSize;
+        }
+    }
+    return baseName;
+}
+
+//eof
+U_NAMESPACE_END
diff --git a/icu/source/common/loclikely.cpp b/icu/source/common/loclikely.cpp
new file mode 100644
index 0000000..0668b6f
--- /dev/null
+++ b/icu/source/common/loclikely.cpp
@@ -0,0 +1,1262 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 1997-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  loclikely.cpp
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2010feb25
+*   created by: Markus W. Scherer
+*
+*   Code for likely and minimized locale subtags, separated out from other .cpp files
+*   that then do not depend on resource bundle code and likely-subtags data.
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/putil.h"
+#include "unicode/uloc.h"
+#include "unicode/ures.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "ulocimp.h"
+#include "ustr_imp.h"
+
+/**
+ * This function looks for the localeID in the likelySubtags resource.
+ *
+ * @param localeID The tag to find.
+ * @param buffer A buffer to hold the matching entry
+ * @param bufferLength The length of the output buffer
+ * @return A pointer to "buffer" if found, or a null pointer if not.
+ */
+static const char*  U_CALLCONV
+findLikelySubtags(const char* localeID,
+                  char* buffer,
+                  int32_t bufferLength,
+                  UErrorCode* err) {
+    const char* result = NULL;
+
+    if (!U_FAILURE(*err)) {
+        int32_t resLen = 0;
+        const UChar* s = NULL;
+        UErrorCode tmpErr = U_ZERO_ERROR;
+        UResourceBundle* subtags = ures_openDirect(NULL, "likelySubtags", &tmpErr);
+        if (U_SUCCESS(tmpErr)) {
+            s = ures_getStringByKey(subtags, localeID, &resLen, &tmpErr);
+
+            if (U_FAILURE(tmpErr)) {
+                /*
+                 * If a resource is missing, it's not really an error, it's
+                 * just that we don't have any data for that particular locale ID.
+                 */
+                if (tmpErr != U_MISSING_RESOURCE_ERROR) {
+                    *err = tmpErr;
+                }
+            }
+            else if (resLen >= bufferLength) {
+                /* The buffer should never overflow. */
+                *err = U_INTERNAL_PROGRAM_ERROR;
+            }
+            else {
+                u_UCharsToChars(s, buffer, resLen + 1);
+                result = buffer;
+            }
+
+            ures_close(subtags);
+        } else {
+            *err = tmpErr;
+        }
+    }
+
+    return result;
+}
+
+/**
+ * Append a tag to a buffer, adding the separator if necessary.  The buffer
+ * must be large enough to contain the resulting tag plus any separator
+ * necessary. The tag must not be a zero-length string.
+ *
+ * @param tag The tag to add.
+ * @param tagLength The length of the tag.
+ * @param buffer The output buffer.
+ * @param bufferLength The length of the output buffer.  This is an input/ouput parameter.
+ **/
+static void U_CALLCONV
+appendTag(
+    const char* tag,
+    int32_t tagLength,
+    char* buffer,
+    int32_t* bufferLength) {
+
+    if (*bufferLength > 0) {
+        buffer[*bufferLength] = '_';
+        ++(*bufferLength);
+    }
+
+    uprv_memmove(
+        &buffer[*bufferLength],
+        tag,
+        tagLength);
+
+    *bufferLength += tagLength;
+}
+
+/**
+ * These are the canonical strings for unknown languages, scripts and regions.
+ **/
+static const char* const unknownLanguage = "und";
+static const char* const unknownScript = "Zzzz";
+static const char* const unknownRegion = "ZZ";
+
+/**
+ * Create a tag string from the supplied parameters.  The lang, script and region
+ * parameters may be NULL pointers. If they are, their corresponding length parameters
+ * must be less than or equal to 0.
+ *
+ * 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.
+ *
+ * If the length of the new string exceeds the capacity of the output buffer, 
+ * the function copies as many bytes to the output buffer as it can, and returns
+ * the error U_BUFFER_OVERFLOW_ERROR.
+ *
+ * If an illegal argument is provided, the function returns the error
+ * U_ILLEGAL_ARGUMENT_ERROR.
+ *
+ * Note that this function can return the warning U_STRING_NOT_TERMINATED_WARNING if
+ * the tag string fits in the output buffer, but the null terminator doesn't.
+ *
+ * @param lang The language tag to use.
+ * @param langLength The length of the language tag.
+ * @param script The script tag to use.
+ * @param scriptLength The length of the script tag.
+ * @param region The region tag to use.
+ * @param regionLength The length of the region tag.
+ * @param trailing Any trailing data to append to the new tag.
+ * @param trailingLength The length of the trailing data.
+ * @param alternateTags A string containing any alternate tags.
+ * @param tag The output buffer.
+ * @param tagCapacity The capacity of the output buffer.
+ * @param err A pointer to a UErrorCode for error reporting.
+ * @return The length of the tag string, which may be greater than tagCapacity, or -1 on error.
+ **/
+static int32_t U_CALLCONV
+createTagStringWithAlternates(
+    const char* lang,
+    int32_t langLength,
+    const char* script,
+    int32_t scriptLength,
+    const char* region,
+    int32_t regionLength,
+    const char* trailing,
+    int32_t trailingLength,
+    const char* alternateTags,
+    char* tag,
+    int32_t tagCapacity,
+    UErrorCode* err) {
+
+    if (U_FAILURE(*err)) {
+        goto error;
+    }
+    else if (tag == NULL ||
+             tagCapacity <= 0 ||
+             langLength >= ULOC_LANG_CAPACITY ||
+             scriptLength >= ULOC_SCRIPT_CAPACITY ||
+             regionLength >= ULOC_COUNTRY_CAPACITY) {
+        goto error;
+    }
+    else {
+        /**
+         * ULOC_FULLNAME_CAPACITY will provide enough capacity
+         * that we can build a string that contains the language,
+         * script and region code without worrying about overrunning
+         * the user-supplied buffer.
+         **/
+        char tagBuffer[ULOC_FULLNAME_CAPACITY];
+        int32_t tagLength = 0;
+        int32_t capacityRemaining = tagCapacity;
+        UBool regionAppended = FALSE;
+
+        if (langLength > 0) {
+            appendTag(
+                lang,
+                langLength,
+                tagBuffer,
+                &tagLength);
+        }
+        else if (alternateTags == NULL) {
+            /*
+             * Append the value for an unknown language, if
+             * we found no language.
+             */
+            appendTag(
+                unknownLanguage,
+                (int32_t)uprv_strlen(unknownLanguage),
+                tagBuffer,
+                &tagLength);
+        }
+        else {
+            /*
+             * Parse the alternateTags string for the language.
+             */
+            char alternateLang[ULOC_LANG_CAPACITY];
+            int32_t alternateLangLength = sizeof(alternateLang);
+
+            alternateLangLength =
+                uloc_getLanguage(
+                    alternateTags,
+                    alternateLang,
+                    alternateLangLength,
+                    err);
+            if(U_FAILURE(*err) ||
+                alternateLangLength >= ULOC_LANG_CAPACITY) {
+                goto error;
+            }
+            else if (alternateLangLength == 0) {
+                /*
+                 * Append the value for an unknown language, if
+                 * we found no language.
+                 */
+                appendTag(
+                    unknownLanguage,
+                    (int32_t)uprv_strlen(unknownLanguage),
+                    tagBuffer,
+                    &tagLength);
+            }
+            else {
+                appendTag(
+                    alternateLang,
+                    alternateLangLength,
+                    tagBuffer,
+                    &tagLength);
+            }
+        }
+
+        if (scriptLength > 0) {
+            appendTag(
+                script,
+                scriptLength,
+                tagBuffer,
+                &tagLength);
+        }
+        else if (alternateTags != NULL) {
+            /*
+             * Parse the alternateTags string for the script.
+             */
+            char alternateScript[ULOC_SCRIPT_CAPACITY];
+
+            const int32_t alternateScriptLength =
+                uloc_getScript(
+                    alternateTags,
+                    alternateScript,
+                    sizeof(alternateScript),
+                    err);
+
+            if (U_FAILURE(*err) ||
+                alternateScriptLength >= ULOC_SCRIPT_CAPACITY) {
+                goto error;
+            }
+            else if (alternateScriptLength > 0) {
+                appendTag(
+                    alternateScript,
+                    alternateScriptLength,
+                    tagBuffer,
+                    &tagLength);
+            }
+        }
+
+        if (regionLength > 0) {
+            appendTag(
+                region,
+                regionLength,
+                tagBuffer,
+                &tagLength);
+
+            regionAppended = TRUE;
+        }
+        else if (alternateTags != NULL) {
+            /*
+             * Parse the alternateTags string for the region.
+             */
+            char alternateRegion[ULOC_COUNTRY_CAPACITY];
+
+            const int32_t alternateRegionLength =
+                uloc_getCountry(
+                    alternateTags,
+                    alternateRegion,
+                    sizeof(alternateRegion),
+                    err);
+            if (U_FAILURE(*err) ||
+                alternateRegionLength >= ULOC_COUNTRY_CAPACITY) {
+                goto error;
+            }
+            else if (alternateRegionLength > 0) {
+                appendTag(
+                    alternateRegion,
+                    alternateRegionLength,
+                    tagBuffer,
+                    &tagLength);
+
+                regionAppended = TRUE;
+            }
+        }
+
+        {
+            const int32_t toCopy =
+                tagLength >= tagCapacity ? tagCapacity : tagLength;
+
+            /**
+             * Copy the partial tag from our internal buffer to the supplied
+             * target.
+             **/
+            uprv_memcpy(
+                tag,
+                tagBuffer,
+                toCopy);
+
+            capacityRemaining -= toCopy;
+        }
+
+        if (trailingLength > 0) {
+            if (capacityRemaining > 0 && !regionAppended) {
+                tag[tagLength++] = '_';
+                --capacityRemaining;
+            }
+
+            if (capacityRemaining > 0) {
+                /*
+                 * Copy the trailing data into the supplied buffer.  Use uprv_memmove, since we
+                 * don't know if the user-supplied buffers overlap.
+                 */
+                const int32_t toCopy =
+                    trailingLength >= capacityRemaining ? capacityRemaining : trailingLength;
+
+                uprv_memmove(
+                    &tag[tagLength],
+                    trailing,
+                    toCopy);
+            }
+        }
+
+        tagLength += trailingLength;
+
+        return u_terminateChars(
+                    tag,
+                    tagCapacity,
+                    tagLength,
+                    err);
+    }
+
+error:
+
+    /**
+     * An overflow indicates the locale ID passed in
+     * is ill-formed.  If we got here, and there was
+     * no previous error, it's an implicit overflow.
+     **/
+    if (*err ==  U_BUFFER_OVERFLOW_ERROR ||
+        U_SUCCESS(*err)) {
+        *err = U_ILLEGAL_ARGUMENT_ERROR;
+    }
+
+    return -1;
+}
+
+/**
+ * Create a tag string from the supplied parameters.  The lang, script and region
+ * parameters may be NULL pointers. If they are, their corresponding length parameters
+ * must be less than or equal to 0.  If the lang parameter is an empty string, the
+ * default value for an unknown language is written to the output buffer.
+ *
+ * If the length of the new string exceeds the capacity of the output buffer, 
+ * the function copies as many bytes to the output buffer as it can, and returns
+ * the error U_BUFFER_OVERFLOW_ERROR.
+ *
+ * If an illegal argument is provided, the function returns the error
+ * U_ILLEGAL_ARGUMENT_ERROR.
+ *
+ * @param lang The language tag to use.
+ * @param langLength The length of the language tag.
+ * @param script The script tag to use.
+ * @param scriptLength The length of the script tag.
+ * @param region The region tag to use.
+ * @param regionLength The length of the region tag.
+ * @param trailing Any trailing data to append to the new tag.
+ * @param trailingLength The length of the trailing data.
+ * @param tag The output buffer.
+ * @param tagCapacity The capacity of the output buffer.
+ * @param err A pointer to a UErrorCode for error reporting.
+ * @return The length of the tag string, which may be greater than tagCapacity.
+ **/
+static int32_t U_CALLCONV
+createTagString(
+    const char* lang,
+    int32_t langLength,
+    const char* script,
+    int32_t scriptLength,
+    const char* region,
+    int32_t regionLength,
+    const char* trailing,
+    int32_t trailingLength,
+    char* tag,
+    int32_t tagCapacity,
+    UErrorCode* err)
+{
+    return createTagStringWithAlternates(
+                lang,
+                langLength,
+                script,
+                scriptLength,
+                region,
+                regionLength,
+                trailing,
+                trailingLength,
+                NULL,
+                tag,
+                tagCapacity,
+                err);
+}
+
+/**
+ * Parse the language, script, and region subtags from a tag string, and copy the
+ * results into the corresponding output parameters. The buffers are null-terminated,
+ * unless overflow occurs.
+ *
+ * The langLength, scriptLength, and regionLength parameters are input/output
+ * parameters, and must contain the capacity of their corresponding buffers on
+ * input.  On output, they will contain the actual length of the buffers, not
+ * including the null terminator.
+ *
+ * If the length of any of the output subtags exceeds the capacity of the corresponding
+ * buffer, the function copies as many bytes to the output buffer as it can, and returns
+ * the error U_BUFFER_OVERFLOW_ERROR.  It will not parse any more subtags once overflow
+ * occurs.
+ *
+ * If an illegal argument is provided, the function returns the error
+ * U_ILLEGAL_ARGUMENT_ERROR.
+ *
+ * @param localeID The locale ID to parse.
+ * @param lang The language tag buffer.
+ * @param langLength The length of the language tag.
+ * @param script The script tag buffer.
+ * @param scriptLength The length of the script tag.
+ * @param region The region tag buffer.
+ * @param regionLength The length of the region tag.
+ * @param err A pointer to a UErrorCode for error reporting.
+ * @return The number of chars of the localeID parameter consumed.
+ **/
+static int32_t U_CALLCONV
+parseTagString(
+    const char* localeID,
+    char* lang,
+    int32_t* langLength,
+    char* script,
+    int32_t* scriptLength,
+    char* region,
+    int32_t* regionLength,
+    UErrorCode* err)
+{
+    const char* position = localeID;
+    int32_t subtagLength = 0;
+
+    if(U_FAILURE(*err) ||
+       localeID == NULL ||
+       lang == NULL ||
+       langLength == NULL ||
+       script == NULL ||
+       scriptLength == NULL ||
+       region == NULL ||
+       regionLength == NULL) {
+        goto error;
+    }
+
+    subtagLength = ulocimp_getLanguage(position, lang, *langLength, &position);
+    u_terminateChars(lang, *langLength, subtagLength, err);
+
+    /*
+     * Note that we explicit consider U_STRING_NOT_TERMINATED_WARNING
+     * to be an error, because it indicates the user-supplied tag is
+     * not well-formed.
+     */
+    if(U_FAILURE(*err)) {
+        goto error;
+    }
+
+    *langLength = subtagLength;
+
+    /*
+     * If no language was present, use the value of unknownLanguage
+     * instead.  Otherwise, move past any separator.
+     */
+    if (*langLength == 0) {
+        uprv_strcpy(
+            lang,
+            unknownLanguage);
+        *langLength = (int32_t)uprv_strlen(lang);
+    }
+    else if (_isIDSeparator(*position)) {
+        ++position;
+    }
+
+    subtagLength = ulocimp_getScript(position, script, *scriptLength, &position);
+    u_terminateChars(script, *scriptLength, subtagLength, err);
+
+    if(U_FAILURE(*err)) {
+        goto error;
+    }
+
+    *scriptLength = subtagLength;
+
+    if (*scriptLength > 0) {
+        if (uprv_strnicmp(script, unknownScript, *scriptLength) == 0) {
+            /**
+             * If the script part is the "unknown" script, then don't return it.
+             **/
+            *scriptLength = 0;
+        }
+
+        /*
+         * Move past any separator.
+         */
+        if (_isIDSeparator(*position)) {
+            ++position;
+        }    
+    }
+
+    subtagLength = ulocimp_getCountry(position, region, *regionLength, &position);
+    u_terminateChars(region, *regionLength, subtagLength, err);
+
+    if(U_FAILURE(*err)) {
+        goto error;
+    }
+
+    *regionLength = subtagLength;
+
+    if (*regionLength > 0) {
+        if (uprv_strnicmp(region, unknownRegion, *regionLength) == 0) {
+            /**
+             * If the region part is the "unknown" region, then don't return it.
+             **/
+            *regionLength = 0;
+        }
+    }
+
+exit:
+
+    return (int32_t)(position - localeID);
+
+error:
+
+    /**
+     * If we get here, we have no explicit error, it's the result of an
+     * illegal argument.
+     **/
+    if (!U_FAILURE(*err)) {
+        *err = U_ILLEGAL_ARGUMENT_ERROR;
+    }
+
+    goto exit;
+}
+
+static int32_t U_CALLCONV
+createLikelySubtagsString(
+    const char* lang,
+    int32_t langLength,
+    const char* script,
+    int32_t scriptLength,
+    const char* region,
+    int32_t regionLength,
+    const char* variants,
+    int32_t variantsLength,
+    char* tag,
+    int32_t tagCapacity,
+    UErrorCode* err)
+{
+    /**
+     * ULOC_FULLNAME_CAPACITY will provide enough capacity
+     * that we can build a string that contains the language,
+     * script and region code without worrying about overrunning
+     * the user-supplied buffer.
+     **/
+    char tagBuffer[ULOC_FULLNAME_CAPACITY];
+    char likelySubtagsBuffer[ULOC_FULLNAME_CAPACITY];
+    int32_t tagBufferLength = 0;
+
+    if(U_FAILURE(*err)) {
+        goto error;
+    }
+
+    /**
+     * Try the language with the script and region first.
+     **/
+    if (scriptLength > 0 && regionLength > 0) {
+
+        const char* likelySubtags = NULL;
+
+        tagBufferLength = createTagString(
+            lang,
+            langLength,
+            script,
+            scriptLength,
+            region,
+            regionLength,
+            NULL,
+            0,
+            tagBuffer,
+            sizeof(tagBuffer),
+            err);
+        if(U_FAILURE(*err)) {
+            goto error;
+        }
+
+        likelySubtags =
+            findLikelySubtags(
+                tagBuffer,
+                likelySubtagsBuffer,
+                sizeof(likelySubtagsBuffer),
+                err);
+        if(U_FAILURE(*err)) {
+            goto error;
+        }
+
+        if (likelySubtags != NULL) {
+            /* Always use the language tag from the
+               maximal string, since it may be more
+               specific than the one provided. */
+            return createTagStringWithAlternates(
+                        NULL,
+                        0,
+                        NULL,
+                        0,
+                        NULL,
+                        0,
+                        variants,
+                        variantsLength,
+                        likelySubtags,
+                        tag,
+                        tagCapacity,
+                        err);
+        }
+    }
+
+    /**
+     * Try the language with just the script.
+     **/
+    if (scriptLength > 0) {
+
+        const char* likelySubtags = NULL;
+
+        tagBufferLength = createTagString(
+            lang,
+            langLength,
+            script,
+            scriptLength,
+            NULL,
+            0,
+            NULL,
+            0,
+            tagBuffer,
+            sizeof(tagBuffer),
+            err);
+        if(U_FAILURE(*err)) {
+            goto error;
+        }
+
+        likelySubtags =
+            findLikelySubtags(
+                tagBuffer,
+                likelySubtagsBuffer,
+                sizeof(likelySubtagsBuffer),
+                err);
+        if(U_FAILURE(*err)) {
+            goto error;
+        }
+
+        if (likelySubtags != NULL) {
+            /* Always use the language tag from the
+               maximal string, since it may be more
+               specific than the one provided. */
+            return createTagStringWithAlternates(
+                        NULL,
+                        0,
+                        NULL,
+                        0,
+                        region,
+                        regionLength,
+                        variants,
+                        variantsLength,
+                        likelySubtags,
+                        tag,
+                        tagCapacity,
+                        err);
+        }
+    }
+
+    /**
+     * Try the language with just the region.
+     **/
+    if (regionLength > 0) {
+
+        const char* likelySubtags = NULL;
+
+        createTagString(
+            lang,
+            langLength,
+            NULL,
+            0,
+            region,
+            regionLength,
+            NULL,
+            0,
+            tagBuffer,
+            sizeof(tagBuffer),
+            err);
+        if(U_FAILURE(*err)) {
+            goto error;
+        }
+
+        likelySubtags =
+            findLikelySubtags(
+                tagBuffer,
+                likelySubtagsBuffer,
+                sizeof(likelySubtagsBuffer),
+                err);
+        if(U_FAILURE(*err)) {
+            goto error;
+        }
+
+        if (likelySubtags != NULL) {
+            /* Always use the language tag from the
+               maximal string, since it may be more
+               specific than the one provided. */
+            return createTagStringWithAlternates(
+                        NULL,
+                        0,
+                        script,
+                        scriptLength,
+                        NULL,
+                        0,
+                        variants,
+                        variantsLength,
+                        likelySubtags,
+                        tag,
+                        tagCapacity,
+                        err);
+        }
+    }
+
+    /**
+     * Finally, try just the language.
+     **/
+    {
+        const char* likelySubtags = NULL;
+
+        createTagString(
+            lang,
+            langLength,
+            NULL,
+            0,
+            NULL,
+            0,
+            NULL,
+            0,
+            tagBuffer,
+            sizeof(tagBuffer),
+            err);
+        if(U_FAILURE(*err)) {
+            goto error;
+        }
+
+        likelySubtags =
+            findLikelySubtags(
+                tagBuffer,
+                likelySubtagsBuffer,
+                sizeof(likelySubtagsBuffer),
+                err);
+        if(U_FAILURE(*err)) {
+            goto error;
+        }
+
+        if (likelySubtags != NULL) {
+            /* Always use the language tag from the
+               maximal string, since it may be more
+               specific than the one provided. */
+            return createTagStringWithAlternates(
+                        NULL,
+                        0,
+                        script,
+                        scriptLength,
+                        region,
+                        regionLength,
+                        variants,
+                        variantsLength,
+                        likelySubtags,
+                        tag,
+                        tagCapacity,
+                        err);
+        }
+    }
+
+    return u_terminateChars(
+                tag,
+                tagCapacity,
+                0,
+                err);
+
+error:
+
+    if (!U_FAILURE(*err)) {
+        *err = U_ILLEGAL_ARGUMENT_ERROR;
+    }
+
+    return -1;
+}
+
+#define CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength) \
+    {   int32_t count = 0; \
+        int32_t i; \
+        for (i = 0; i < trailingLength; i++) { \
+            if (trailing[i] == '-' || trailing[i] == '_') { \
+                count = 0; \
+                if (count > 8) { \
+                    goto error; \
+                } \
+            } else if (trailing[i] == '@') { \
+                break; \
+            } else if (count > 8) { \
+                goto error; \
+            } else { \
+                count++; \
+            } \
+        } \
+    }
+
+static int32_t
+_uloc_addLikelySubtags(const char*    localeID,
+         char* maximizedLocaleID,
+         int32_t maximizedLocaleIDCapacity,
+         UErrorCode* err)
+{
+    char lang[ULOC_LANG_CAPACITY];
+    int32_t langLength = sizeof(lang);
+    char script[ULOC_SCRIPT_CAPACITY];
+    int32_t scriptLength = sizeof(script);
+    char region[ULOC_COUNTRY_CAPACITY];
+    int32_t regionLength = sizeof(region);
+    const char* trailing = "";
+    int32_t trailingLength = 0;
+    int32_t trailingIndex = 0;
+    int32_t resultLength = 0;
+
+    if(U_FAILURE(*err)) {
+        goto error;
+    }
+    else if (localeID == NULL ||
+             maximizedLocaleID == NULL ||
+             maximizedLocaleIDCapacity <= 0) {
+        goto error;
+    }
+
+    trailingIndex = parseTagString(
+        localeID,
+        lang,
+        &langLength,
+        script,
+        &scriptLength,
+        region,
+        &regionLength,
+        err);
+    if(U_FAILURE(*err)) {
+        /* Overflow indicates an illegal argument error */
+        if (*err == U_BUFFER_OVERFLOW_ERROR) {
+            *err = U_ILLEGAL_ARGUMENT_ERROR;
+        }
+
+        goto error;
+    }
+
+    /* Find the length of the trailing portion. */
+    trailing = &localeID[trailingIndex];
+    trailingLength = (int32_t)uprv_strlen(trailing);
+
+    CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength);
+
+    resultLength =
+        createLikelySubtagsString(
+            lang,
+            langLength,
+            script,
+            scriptLength,
+            region,
+            regionLength,
+            trailing,
+            trailingLength,
+            maximizedLocaleID,
+            maximizedLocaleIDCapacity,
+            err);
+
+    if (resultLength == 0) {
+        const int32_t localIDLength = (int32_t)uprv_strlen(localeID);
+
+        /*
+         * If we get here, we need to return localeID.
+         */
+        uprv_memcpy(
+            maximizedLocaleID,
+            localeID,
+            localIDLength <= maximizedLocaleIDCapacity ? 
+                localIDLength : maximizedLocaleIDCapacity);
+
+        resultLength =
+            u_terminateChars(
+                maximizedLocaleID,
+                maximizedLocaleIDCapacity,
+                localIDLength,
+                err);
+    }
+
+    return resultLength;
+
+error:
+
+    if (!U_FAILURE(*err)) {
+        *err = U_ILLEGAL_ARGUMENT_ERROR;
+    }
+
+    return -1;
+}
+
+static int32_t
+_uloc_minimizeSubtags(const char*    localeID,
+         char* minimizedLocaleID,
+         int32_t minimizedLocaleIDCapacity,
+         UErrorCode* err)
+{
+    /**
+     * ULOC_FULLNAME_CAPACITY will provide enough capacity
+     * that we can build a string that contains the language,
+     * script and region code without worrying about overrunning
+     * the user-supplied buffer.
+     **/
+    char maximizedTagBuffer[ULOC_FULLNAME_CAPACITY];
+    int32_t maximizedTagBufferLength = sizeof(maximizedTagBuffer);
+
+    char lang[ULOC_LANG_CAPACITY];
+    int32_t langLength = sizeof(lang);
+    char script[ULOC_SCRIPT_CAPACITY];
+    int32_t scriptLength = sizeof(script);
+    char region[ULOC_COUNTRY_CAPACITY];
+    int32_t regionLength = sizeof(region);
+    const char* trailing = "";
+    int32_t trailingLength = 0;
+    int32_t trailingIndex = 0;
+
+    if(U_FAILURE(*err)) {
+        goto error;
+    }
+    else if (localeID == NULL ||
+             minimizedLocaleID == NULL ||
+             minimizedLocaleIDCapacity <= 0) {
+        goto error;
+    }
+
+    trailingIndex =
+        parseTagString(
+            localeID,
+            lang,
+            &langLength,
+            script,
+            &scriptLength,
+            region,
+            &regionLength,
+            err);
+    if(U_FAILURE(*err)) {
+
+        /* Overflow indicates an illegal argument error */
+        if (*err == U_BUFFER_OVERFLOW_ERROR) {
+            *err = U_ILLEGAL_ARGUMENT_ERROR;
+        }
+
+        goto error;
+    }
+
+    /* Find the spot where the variants begin, if any. */
+    trailing = &localeID[trailingIndex];
+    trailingLength = (int32_t)uprv_strlen(trailing);
+
+    CHECK_TRAILING_VARIANT_SIZE(trailing, trailingLength);
+
+    createTagString(
+        lang,
+        langLength,
+        script,
+        scriptLength,
+        region,
+        regionLength,
+        NULL,
+        0,
+        maximizedTagBuffer,
+        maximizedTagBufferLength,
+        err);
+    if(U_FAILURE(*err)) {
+        goto error;
+    }
+
+    /**
+     * First, we need to first get the maximization
+     * from AddLikelySubtags.
+     **/
+    maximizedTagBufferLength =
+        uloc_addLikelySubtags(
+            maximizedTagBuffer,
+            maximizedTagBuffer,
+            maximizedTagBufferLength,
+            err);
+
+    if(U_FAILURE(*err)) {
+        goto error;
+    }
+
+    /**
+     * Start first with just the language.
+     **/
+    {
+        char tagBuffer[ULOC_FULLNAME_CAPACITY];
+
+        const int32_t tagBufferLength =
+            createLikelySubtagsString(
+                lang,
+                langLength,
+                NULL,
+                0,
+                NULL,
+                0,
+                NULL,
+                0,
+                tagBuffer,
+                sizeof(tagBuffer),
+                err);
+
+        if(U_FAILURE(*err)) {
+            goto error;
+        }
+        else if (uprv_strnicmp(
+                    maximizedTagBuffer,
+                    tagBuffer,
+                    tagBufferLength) == 0) {
+
+            return createTagString(
+                        lang,
+                        langLength,
+                        NULL,
+                        0,
+                        NULL,
+                        0,
+                        trailing,
+                        trailingLength,
+                        minimizedLocaleID,
+                        minimizedLocaleIDCapacity,
+                        err);
+        }
+    }
+
+    /**
+     * Next, try the language and region.
+     **/
+    if (regionLength > 0) {
+
+        char tagBuffer[ULOC_FULLNAME_CAPACITY];
+
+        const int32_t tagBufferLength =
+            createLikelySubtagsString(
+                lang,
+                langLength,
+                NULL,
+                0,
+                region,
+                regionLength,
+                NULL,
+                0,
+                tagBuffer,
+                sizeof(tagBuffer),
+                err);
+
+        if(U_FAILURE(*err)) {
+            goto error;
+        }
+        else if (uprv_strnicmp(
+                    maximizedTagBuffer,
+                    tagBuffer,
+                    tagBufferLength) == 0) {
+
+            return createTagString(
+                        lang,
+                        langLength,
+                        NULL,
+                        0,
+                        region,
+                        regionLength,
+                        trailing,
+                        trailingLength,
+                        minimizedLocaleID,
+                        minimizedLocaleIDCapacity,
+                        err);
+        }
+    }
+
+    /**
+     * Finally, try the language and script.  This is our last chance,
+     * since trying with all three subtags would only yield the
+     * maximal version that we already have.
+     **/
+    if (scriptLength > 0 && regionLength > 0) {
+        char tagBuffer[ULOC_FULLNAME_CAPACITY];
+
+        const int32_t tagBufferLength =
+            createLikelySubtagsString(
+                lang,
+                langLength,
+                script,
+                scriptLength,
+                NULL,
+                0,
+                NULL,
+                0,
+                tagBuffer,
+                sizeof(tagBuffer),
+                err);
+
+        if(U_FAILURE(*err)) {
+            goto error;
+        }
+        else if (uprv_strnicmp(
+                    maximizedTagBuffer,
+                    tagBuffer,
+                    tagBufferLength) == 0) {
+
+            return createTagString(
+                        lang,
+                        langLength,
+                        script,
+                        scriptLength,
+                        NULL,
+                        0,
+                        trailing,
+                        trailingLength,
+                        minimizedLocaleID,
+                        minimizedLocaleIDCapacity,
+                        err);
+        }
+    }
+
+    {
+        /**
+         * If we got here, return the locale ID parameter.
+         **/
+        const int32_t localeIDLength = (int32_t)uprv_strlen(localeID);
+
+        uprv_memcpy(
+            minimizedLocaleID,
+            localeID,
+            localeIDLength <= minimizedLocaleIDCapacity ? 
+                localeIDLength : minimizedLocaleIDCapacity);
+
+        return u_terminateChars(
+                    minimizedLocaleID,
+                    minimizedLocaleIDCapacity,
+                    localeIDLength,
+                    err);
+    }
+
+error:
+
+    if (!U_FAILURE(*err)) {
+        *err = U_ILLEGAL_ARGUMENT_ERROR;
+    }
+
+    return -1;
+
+
+}
+
+static UBool
+do_canonicalize(const char*    localeID,
+         char* buffer,
+         int32_t bufferCapacity,
+         UErrorCode* err)
+{
+    uloc_canonicalize(
+        localeID,
+        buffer,
+        bufferCapacity,
+        err);
+
+    if (*err == U_STRING_NOT_TERMINATED_WARNING ||
+        *err == U_BUFFER_OVERFLOW_ERROR) {
+        *err = U_ILLEGAL_ARGUMENT_ERROR;
+
+        return FALSE;
+    }
+    else if (U_FAILURE(*err)) {
+
+        return FALSE;
+    }
+    else {
+        return TRUE;
+    }
+}
+
+U_DRAFT int32_t U_EXPORT2
+uloc_addLikelySubtags(const char*    localeID,
+         char* maximizedLocaleID,
+         int32_t maximizedLocaleIDCapacity,
+         UErrorCode* err)
+{
+    char localeBuffer[ULOC_FULLNAME_CAPACITY];
+
+    if (!do_canonicalize(
+        localeID,
+        localeBuffer,
+        sizeof(localeBuffer),
+        err)) {
+        return -1;
+    }
+    else {
+        return _uloc_addLikelySubtags(
+                    localeBuffer,
+                    maximizedLocaleID,
+                    maximizedLocaleIDCapacity,
+                    err);
+    }    
+}
+
+U_DRAFT int32_t U_EXPORT2
+uloc_minimizeSubtags(const char*    localeID,
+         char* minimizedLocaleID,
+         int32_t minimizedLocaleIDCapacity,
+         UErrorCode* err)
+{
+    char localeBuffer[ULOC_FULLNAME_CAPACITY];
+
+    if (!do_canonicalize(
+        localeID,
+        localeBuffer,
+        sizeof(localeBuffer),
+        err)) {
+        return -1;
+    }
+    else {
+        return _uloc_minimizeSubtags(
+                    localeBuffer,
+                    minimizedLocaleID,
+                    minimizedLocaleIDCapacity,
+                    err);
+    }    
+}
diff --git a/icu/source/common/locmap.c b/icu/source/common/locmap.c
new file mode 100644
index 0000000..a11c538
--- /dev/null
+++ b/icu/source/common/locmap.c
@@ -0,0 +1,989 @@
+/*
+ **********************************************************************
+ *   Copyright (C) 1996-2010, International Business Machines
+ *   Corporation and others.  All Rights Reserved.
+ **********************************************************************
+ *
+ * Provides functionality for mapping between
+ * LCID and Posix IDs or ICU locale to codepage
+ *
+ * Note: All classes and code in this file are
+ *       intended for internal use only.
+ *
+ * Methods of interest:
+ *   unsigned long convertToLCID(const char*);
+ *   const char* convertToPosix(unsigned long);
+ *
+ * Kathleen Wilson, 4/30/96
+ *
+ *  Date        Name        Description
+ *  3/11/97     aliu        Fixed off-by-one bug in assignment operator. Added
+ *                          setId() method and safety check against 
+ *                          MAX_ID_LENGTH.
+ * 04/23/99     stephen     Added C wrapper for convertToPosix.
+ * 09/18/00     george      Removed the memory leaks.
+ * 08/23/01     george      Convert to C
+ */
+
+#include "locmap.h"
+#include "unicode/uloc.h"
+#include "cstring.h"
+#include "cmemory.h"
+
+#if defined(U_WINDOWS) && defined(_MSC_VER) && (_MSC_VER >= 1500)
+#define USE_WINDOWS_LOCALE_API
+#endif
+
+#ifdef USE_WINDOWS_LOCALE_API
+#include <windows.h>
+#include <winnls.h>
+#endif
+
+/*
+ * Note:
+ * The mapping from Win32 locale ID numbers to POSIX locale strings should
+ * be the faster one.
+ *
+ * Many LCID values come from winnt.h
+ * Some also come from http://www.microsoft.com/globaldev/reference/lcid-all.mspx
+ */
+
+/*
+////////////////////////////////////////////////
+//
+// Internal Classes for LCID <--> POSIX Mapping
+//
+/////////////////////////////////////////////////
+*/
+
+typedef struct ILcidPosixElement
+{
+    const uint32_t hostID;
+    const char * const posixID;
+} ILcidPosixElement;
+
+typedef struct ILcidPosixMap
+{
+    const uint32_t numRegions;
+    const struct ILcidPosixElement* const regionMaps;
+} ILcidPosixMap;
+
+
+/*
+/////////////////////////////////////////////////
+//
+// Easy macros to make the LCID <--> POSIX Mapping
+//
+/////////////////////////////////////////////////
+*/
+
+/**
+ * The standard one language/one country mapping for LCID.
+ * The first element must be the language, and the following
+ * elements are the language with the country.
+ * @param hostID LCID in host format such as 0x044d
+ * @param languageID posix ID of just the language such as 'de'
+ * @param posixID posix ID of the language_TERRITORY such as 'de_CH'
+ */
+#define ILCID_POSIX_ELEMENT_ARRAY(hostID, languageID, posixID) \
+static const ILcidPosixElement locmap_ ## languageID [] = { \
+    {LANGUAGE_LCID(hostID), #languageID},     /* parent locale */ \
+    {hostID, #posixID}, \
+};
+
+/**
+ * Define a subtable by ID
+ * @param id the POSIX ID, either a language or language_TERRITORY
+ */
+#define ILCID_POSIX_SUBTABLE(id) \
+static const ILcidPosixElement locmap_ ## id [] =
+
+
+/**
+ * Create the map for the posixID. This macro supposes that the language string
+ * name is the same as the global variable name, and that the first element
+ * in the ILcidPosixElement is just the language.
+ * @param _posixID the full POSIX ID for this entry. 
+ */
+#define ILCID_POSIX_MAP(_posixID) \
+    {sizeof(locmap_ ## _posixID)/sizeof(ILcidPosixElement), locmap_ ## _posixID}
+
+/*
+////////////////////////////////////////////
+//
+// Create the table of LCID to POSIX Mapping
+// None of it should be dynamically created.
+//
+// Keep static locale variables inside the function so that
+// it can be created properly during static init.
+//
+// Note: This table should be updated periodically. Check the National Lanaguage Support API Reference Website.
+//       Microsoft is moving away from LCID in favor of locale name as of Vista.  This table needs to be
+//       maintained for support of older Windows version.
+//       Update: Windows 7 (091130)
+////////////////////////////////////////////
+*/
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0436, af, af_ZA)
+
+ILCID_POSIX_SUBTABLE(ar) {
+    {0x01,   "ar"},
+    {0x3801, "ar_AE"},
+    {0x3c01, "ar_BH"},
+    {0x1401, "ar_DZ"},
+    {0x0c01, "ar_EG"},
+    {0x0801, "ar_IQ"},
+    {0x2c01, "ar_JO"},
+    {0x3401, "ar_KW"},
+    {0x3001, "ar_LB"},
+    {0x1001, "ar_LY"},
+    {0x1801, "ar_MA"},
+    {0x2001, "ar_OM"},
+    {0x4001, "ar_QA"},
+    {0x0401, "ar_SA"},
+    {0x2801, "ar_SY"},
+    {0x1c01, "ar_TN"},
+    {0x2401, "ar_YE"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x044d, as, as_IN)
+ILCID_POSIX_ELEMENT_ARRAY(0x045e, am, am_ET)
+ILCID_POSIX_ELEMENT_ARRAY(0x047a, arn,arn_CL)
+
+ILCID_POSIX_SUBTABLE(az) {
+    {0x2c,   "az"},
+    {0x082c, "az_Cyrl_AZ"},  /* Cyrillic based */
+    {0x742c, "az_Cyrl"},  /* Cyrillic based */
+    {0x042c, "az_Latn_AZ"}, /* Latin based */
+    {0x782c, "az_Latn"}, /* Latin based */
+    {0x042c, "az_AZ"} /* Latin based */
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x046d, ba, ba_RU)
+ILCID_POSIX_ELEMENT_ARRAY(0x0423, be, be_BY)
+
+ILCID_POSIX_SUBTABLE(ber) {
+    {0x5f,   "ber"},
+    {0x045f, "ber_Arab_DZ"},
+    {0x045f, "ber_Arab"},
+    {0x085f, "ber_Latn_DZ"},
+    {0x085f, "ber_Latn"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0402, bg, bg_BG)
+
+ILCID_POSIX_SUBTABLE(bn) {
+    {0x45,   "bn"},
+    {0x0845, "bn_BD"},
+    {0x0445, "bn_IN"}
+};
+
+ILCID_POSIX_SUBTABLE(bo) {
+    {0x51,   "bo"},
+    {0x0851, "bo_BT"},
+    {0x0451, "bo_CN"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x047e, br, br_FR)
+ILCID_POSIX_ELEMENT_ARRAY(0x0403, ca, ca_ES)
+ILCID_POSIX_ELEMENT_ARRAY(0x0483, co, co_FR)
+ILCID_POSIX_ELEMENT_ARRAY(0x045c, chr,chr_US)
+
+/* Declared as cs_CZ to get around compiler errors on z/OS, which defines cs as a function */
+ILCID_POSIX_ELEMENT_ARRAY(0x0405, cs, cs_CZ)
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0452, cy, cy_GB)
+ILCID_POSIX_ELEMENT_ARRAY(0x0406, da, da_DK)
+
+ILCID_POSIX_SUBTABLE(de) {
+    {0x07,   "de"},
+    {0x0c07, "de_AT"},
+    {0x0807, "de_CH"},
+    {0x0407, "de_DE"},
+    {0x1407, "de_LI"},
+    {0x1007, "de_LU"},
+    {0x10407,"de_DE@collation=phonebook"},  /*This is really de_DE_PHONEBOOK on Windows*/
+    {0x10407,"de@collation=phonebook"}  /*This is really de_DE_PHONEBOOK on Windows*/
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0465, dv, dv_MV)
+ILCID_POSIX_ELEMENT_ARRAY(0x0408, el, el_GR)
+
+ILCID_POSIX_SUBTABLE(en) {
+    {0x09,   "en"},
+    {0x0c09, "en_AU"},
+    {0x2809, "en_BZ"},
+    {0x1009, "en_CA"},
+    {0x0809, "en_GB"},
+    {0x1809, "en_IE"},
+    {0x4009, "en_IN"},
+    {0x2009, "en_JM"},
+    {0x4409, "en_MY"},
+    {0x1409, "en_NZ"},
+    {0x3409, "en_PH"},
+    {0x4809, "en_SG"},
+    {0x2C09, "en_TT"},
+    {0x0409, "en_US"},
+    {0x007f, "en_US_POSIX"}, /* duplicate for roundtripping */
+    {0x2409, "en_VI"},  /* Virgin Islands AKA Caribbean Islands (en_CB). */
+    {0x1c09, "en_ZA"},
+    {0x3009, "en_ZW"},
+    {0x2409, "en_029"},
+    {0x0409, "en_AS"},  /* Alias for en_US. Leave last. */
+    {0x0409, "en_GU"},  /* Alias for en_US. Leave last. */
+    {0x0409, "en_MH"},  /* Alias for en_US. Leave last. */
+    {0x0409, "en_MP"},  /* Alias for en_US. Leave last. */
+    {0x0409, "en_UM"}   /* Alias for en_US. Leave last. */
+};
+
+ILCID_POSIX_SUBTABLE(en_US_POSIX) {
+    {0x007f, "en_US_POSIX"} /* duplicate for roundtripping */
+};
+
+ILCID_POSIX_SUBTABLE(es) {
+    {0x0a,   "es"},
+    {0x2c0a, "es_AR"},
+    {0x400a, "es_BO"},
+    {0x340a, "es_CL"},
+    {0x240a, "es_CO"},
+    {0x140a, "es_CR"},
+    {0x1c0a, "es_DO"},
+    {0x300a, "es_EC"},
+    {0x0c0a, "es_ES"},      /*Modern sort.*/
+    {0x100a, "es_GT"},
+    {0x480a, "es_HN"},
+    {0x080a, "es_MX"},
+    {0x4c0a, "es_NI"},
+    {0x180a, "es_PA"},
+    {0x280a, "es_PE"},
+    {0x500a, "es_PR"},
+    {0x3c0a, "es_PY"},
+    {0x440a, "es_SV"},
+    {0x540a, "es_US"},
+    {0x380a, "es_UY"},
+    {0x200a, "es_VE"},
+    {0x040a, "es_ES@collation=traditional"},
+    {0x040a, "es@collation=traditional"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0425, et, et_EE)
+ILCID_POSIX_ELEMENT_ARRAY(0x042d, eu, eu_ES)
+
+/* ISO-639 doesn't distinguish between Persian and Dari.*/
+ILCID_POSIX_SUBTABLE(fa) {
+    {0x29,   "fa"},
+    {0x0429, "fa_IR"},  /* Persian/Farsi (Iran) */
+    {0x048c, "fa_AF"}   /* Persian/Dari (Afghanistan) */
+};
+
+/* duplicate for roundtripping */
+ILCID_POSIX_SUBTABLE(fa_AF) {
+    {0x8c,   "fa_AF"},  /* Persian/Dari (Afghanistan) */
+    {0x048c, "fa_AF"}   /* Persian/Dari (Afghanistan) */
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x040b, fi, fi_FI)
+ILCID_POSIX_ELEMENT_ARRAY(0x0464, fil,fil_PH)
+ILCID_POSIX_ELEMENT_ARRAY(0x0438, fo, fo_FO)
+
+ILCID_POSIX_SUBTABLE(fr) {
+    {0x0c,   "fr"},
+    {0x080c, "fr_BE"},
+    {0x0c0c, "fr_CA"},
+    {0x240c, "fr_CD"},
+    {0x100c, "fr_CH"},
+    {0x300c, "fr_CI"},
+    {0x2c0c, "fr_CM"},
+    {0x040c, "fr_FR"},
+    {0x3c0c, "fr_HT"},
+    {0x140c, "fr_LU"},
+    {0x380c, "fr_MA"},
+    {0x180c, "fr_MC"},
+    {0x340c, "fr_ML"},
+    {0x200c, "fr_RE"},
+    {0x280c, "fr_SN"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0462, fy, fy_NL)
+
+/* This LCID is really two different locales.*/
+ILCID_POSIX_ELEMENT_ARRAY(0x083c, ga, ga_IE) /* Gaelic (Ireland) */
+ILCID_POSIX_ELEMENT_ARRAY(0x0491, gd, gd_GB) /* Gaelic (Scotland) */
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0456, gl, gl_ES)
+ILCID_POSIX_ELEMENT_ARRAY(0x0447, gu, gu_IN)
+ILCID_POSIX_ELEMENT_ARRAY(0x0474, gn, gn_PY)
+ILCID_POSIX_ELEMENT_ARRAY(0x0484, gsw,gsw_FR)
+
+ILCID_POSIX_SUBTABLE(ha) {
+    {0x68,   "ha"},
+    {0x7c68, "ha_Latn"},
+    {0x0468, "ha_Latn_NG"},
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0475, haw,haw_US)
+ILCID_POSIX_ELEMENT_ARRAY(0x040d, he, he_IL)
+ILCID_POSIX_ELEMENT_ARRAY(0x0439, hi, hi_IN)
+
+/* This LCID is really four different locales.*/
+ILCID_POSIX_SUBTABLE(hr) {
+    {0x1a,   "hr"},
+    {0x141a, "bs_Latn_BA"},  /* Bosnian, Bosnia and Herzegovina */
+    {0x681a, "bs_Latn"},  /* Bosnian, Bosnia and Herzegovina */
+    {0x141a, "bs_BA"},  /* Bosnian, Bosnia and Herzegovina */
+    {0x781a, "bs"},     /* Bosnian */
+    {0x201a, "bs_Cyrl_BA"},  /* Bosnian, Bosnia and Herzegovina */
+    {0x641a, "bs_Cyrl"},  /* Bosnian, Bosnia and Herzegovina */
+    {0x101a, "hr_BA"},  /* Croatian in Bosnia */
+    {0x041a, "hr_HR"},  /* Croatian*/
+    {0x2c1a, "sr_Latn_ME"},
+    {0x241a, "sr_Latn_RS"},
+    {0x181a, "sr_Latn_BA"}, /* Serbo-Croatian in Bosnia */
+    {0x081a, "sr_Latn_CS"}, /* Serbo-Croatian*/
+    {0x701a, "sr_Latn"},    /* It's 0x1a or 0x081a, pick one to make the test program happy. */
+    {0x1c1a, "sr_Cyrl_BA"}, /* Serbo-Croatian in Bosnia */
+    {0x0c1a, "sr_Cyrl_CS"}, /* Serbian*/
+    {0x301a, "sr_Cyrl_ME"},
+    {0x281a, "sr_Cyrl_RS"},
+    {0x6c1a, "sr_Cyrl"},    /* It's 0x1a or 0x0c1a, pick one to make the test program happy. */
+    {0x7c1a, "sr"}          /* In CLDR sr is sr_Cyrl. */
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x040e, hu, hu_HU)
+ILCID_POSIX_ELEMENT_ARRAY(0x042b, hy, hy_AM)
+ILCID_POSIX_ELEMENT_ARRAY(0x0421, id, id_ID)
+ILCID_POSIX_ELEMENT_ARRAY(0x0470, ig, ig_NG)
+ILCID_POSIX_ELEMENT_ARRAY(0x0478, ii, ii_CN)
+ILCID_POSIX_ELEMENT_ARRAY(0x040f, is, is_IS)
+
+ILCID_POSIX_SUBTABLE(it) {
+    {0x10,   "it"},
+    {0x0810, "it_CH"},
+    {0x0410, "it_IT"}
+};
+
+ILCID_POSIX_SUBTABLE(iu) {
+    {0x5d,   "iu"},
+    {0x045d, "iu_Cans_CA"},
+    {0x785d, "iu_Cans"},
+    {0x085d, "iu_Latn_CA"},
+    {0x7c5d, "iu_Latn"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x040d, iw, iw_IL)    /*Left in for compatibility*/
+ILCID_POSIX_ELEMENT_ARRAY(0x0411, ja, ja_JP)
+ILCID_POSIX_ELEMENT_ARRAY(0x0437, ka, ka_GE)
+ILCID_POSIX_ELEMENT_ARRAY(0x043f, kk, kk_KZ)
+ILCID_POSIX_ELEMENT_ARRAY(0x046f, kl, kl_GL)
+ILCID_POSIX_ELEMENT_ARRAY(0x0453, km, km_KH)
+ILCID_POSIX_ELEMENT_ARRAY(0x044b, kn, kn_IN)
+
+ILCID_POSIX_SUBTABLE(ko) {
+    {0x12,   "ko"},
+    {0x0812, "ko_KP"},
+    {0x0412, "ko_KR"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0457, kok, kok_IN)
+ILCID_POSIX_ELEMENT_ARRAY(0x0471, kr,  kr_NG)
+
+ILCID_POSIX_SUBTABLE(ks) {         /* We could add PK and CN too */
+    {0x60,   "ks"},
+    {0x0860, "ks_IN"},              /* Documentation doesn't mention script */
+    {0x0460, "ks_Arab_IN"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0440, ky, ky_KG)   /* Kyrgyz is spoken in Kyrgyzstan */
+ILCID_POSIX_ELEMENT_ARRAY(0x0476, la, la_IT)   /* TODO: Verify the country */
+ILCID_POSIX_ELEMENT_ARRAY(0x046e, lb, lb_LU)
+ILCID_POSIX_ELEMENT_ARRAY(0x0454, lo, lo_LA)
+ILCID_POSIX_ELEMENT_ARRAY(0x0427, lt, lt_LT)
+ILCID_POSIX_ELEMENT_ARRAY(0x0426, lv, lv_LV)
+ILCID_POSIX_ELEMENT_ARRAY(0x0481, mi, mi_NZ)
+ILCID_POSIX_ELEMENT_ARRAY(0x042f, mk, mk_MK)
+ILCID_POSIX_ELEMENT_ARRAY(0x044c, ml, ml_IN)
+
+ILCID_POSIX_SUBTABLE(mn) {
+    {0x50,   "mn"},
+    {0x0450, "mn_MN"},
+    {0x7c50, "mn_Mong"},
+    {0x0850, "mn_Mong_CN"},
+    {0x0850, "mn_CN"},
+    {0x7850, "mn_Cyrl"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0458, mni,mni_IN)
+ILCID_POSIX_ELEMENT_ARRAY(0x047c, moh,moh_CA)
+ILCID_POSIX_ELEMENT_ARRAY(0x044e, mr, mr_IN)
+
+ILCID_POSIX_SUBTABLE(ms) {
+    {0x3e,   "ms"},
+    {0x083e, "ms_BN"},   /* Brunei Darussalam*/
+    {0x043e, "ms_MY"}    /* Malaysia*/
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x043a, mt, mt_MT)
+ILCID_POSIX_ELEMENT_ARRAY(0x0455, my, my_MM)
+
+ILCID_POSIX_SUBTABLE(ne) {
+    {0x61,   "ne"},
+    {0x0861, "ne_IN"},   /* India*/
+    {0x0461, "ne_NP"}    /* Nepal*/
+};
+
+ILCID_POSIX_SUBTABLE(nl) {
+    {0x13,   "nl"},
+    {0x0813, "nl_BE"},
+    {0x0413, "nl_NL"}
+};
+
+/* The "no" locale split into nb and nn.  By default in ICU, "no" is nb.*/
+ILCID_POSIX_SUBTABLE(no) {
+    {0x14,   "no"},     /* really nb_NO */
+    {0x7c14, "nb"},     /* really nb */
+    {0x0414, "nb_NO"},  /* really nb_NO. Keep first in the 414 list. */
+    {0x0414, "no_NO"},  /* really nb_NO */
+    {0x0814, "nn_NO"},  /* really nn_NO. Keep first in the 814 list.  */
+    {0x7814, "nn"},     /* It's 0x14 or 0x814, pick one to make the test program happy. */
+    {0x0814, "no_NO_NY"}/* really nn_NO */
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x046c, nso,nso_ZA)   /* TODO: Verify the ISO-639 code */
+ILCID_POSIX_ELEMENT_ARRAY(0x0482, oc, oc_FR)
+ILCID_POSIX_ELEMENT_ARRAY(0x0472, om, om_ET)    /* TODO: Verify the country */
+
+/* Declared as or_IN to get around compiler errors*/
+ILCID_POSIX_SUBTABLE(or_IN) {
+    {0x48,   "or"},
+    {0x0448, "or_IN"},
+};
+
+
+ILCID_POSIX_SUBTABLE(pa) {
+    {0x46,   "pa"},
+    {0x0446, "pa_IN"},
+    {0x0846, "pa_PK"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0415, pl, pl_PL)
+ILCID_POSIX_ELEMENT_ARRAY(0x0463, ps, ps_AF)
+
+ILCID_POSIX_SUBTABLE(pt) {
+    {0x16,   "pt"},
+    {0x0416, "pt_BR"},
+    {0x0816, "pt_PT"}
+};
+
+ILCID_POSIX_SUBTABLE(qu) {
+    {0x6b,   "qu"},
+    {0x046b, "qu_BO"},
+    {0x086b, "qu_EC"},
+    {0x0C6b, "qu_PE"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0486, qut, qut_GT) /* qut is an ISO-639-3 code */
+ILCID_POSIX_ELEMENT_ARRAY(0x0417, rm, rm_CH)
+ILCID_POSIX_ELEMENT_ARRAY(0x0418, ro, ro_RO)
+
+ILCID_POSIX_SUBTABLE(root) {
+    {0x00,   "root"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0419, ru, ru_RU)
+ILCID_POSIX_ELEMENT_ARRAY(0x0487, rw, rw_RW)
+ILCID_POSIX_ELEMENT_ARRAY(0x044f, sa, sa_IN)
+ILCID_POSIX_ELEMENT_ARRAY(0x0485, sah,sah_RU)
+
+ILCID_POSIX_SUBTABLE(sd) {
+    {0x59,   "sd"},
+    {0x0459, "sd_IN"},
+    {0x0859, "sd_PK"}
+};
+
+ILCID_POSIX_SUBTABLE(se) {
+    {0x3b,   "se"},
+    {0x0c3b, "se_FI"},
+    {0x043b, "se_NO"},
+    {0x083b, "se_SE"},
+    {0x783b, "sma"},
+    {0x183b, "sma_NO"},
+    {0x1c3b, "sma_SE"},
+    {0x7c3b, "smj"},
+    {0x703b, "smn"},
+    {0x743b, "sms"},
+    {0x103b, "smj_NO"},
+    {0x143b, "smj_SE"},
+    {0x243b, "smn_FI"},
+    {0x203b, "sms_FI"},
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x045b, si, si_LK)
+ILCID_POSIX_ELEMENT_ARRAY(0x041b, sk, sk_SK)
+ILCID_POSIX_ELEMENT_ARRAY(0x0424, sl, sl_SI)
+ILCID_POSIX_ELEMENT_ARRAY(0x0477, so, so_ET)    /* TODO: Verify the country */
+ILCID_POSIX_ELEMENT_ARRAY(0x041c, sq, sq_AL)
+
+ILCID_POSIX_SUBTABLE(sv) {
+    {0x1d,   "sv"},
+    {0x081d, "sv_FI"},
+    {0x041d, "sv_SE"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0441, sw, sw_KE)
+ILCID_POSIX_ELEMENT_ARRAY(0x045A, syr, syr_SY)
+ILCID_POSIX_ELEMENT_ARRAY(0x0449, ta, ta_IN)
+ILCID_POSIX_ELEMENT_ARRAY(0x044a, te, te_IN)
+
+/* Cyrillic based by default */
+ILCID_POSIX_SUBTABLE(tg) {
+    {0x28,   "tg"},
+    {0x7c28, "tg_Cyrl"},
+    {0x0428, "tg_Cyrl_TJ"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x041e, th, th_TH)
+
+ILCID_POSIX_SUBTABLE(ti) {
+    {0x73,   "ti"},
+    {0x0873, "ti_ER"},
+    {0x0473, "ti_ET"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0442, tk, tk_TM)
+ILCID_POSIX_ELEMENT_ARRAY(0x0432, tn, tn_BW)
+ILCID_POSIX_ELEMENT_ARRAY(0x041f, tr, tr_TR)
+ILCID_POSIX_ELEMENT_ARRAY(0x0444, tt, tt_RU)
+
+ILCID_POSIX_SUBTABLE(tzm) {
+    {0x5f,   "tzm"},
+    {0x7c5f, "tzm_Latn"},
+    {0x085f, "tzm_Latn_DZ"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0480, ug, ug_CN)
+ILCID_POSIX_ELEMENT_ARRAY(0x0422, uk, uk_UA)
+
+ILCID_POSIX_SUBTABLE(ur) {
+    {0x20,   "ur"},
+    {0x0820, "ur_IN"},
+    {0x0420, "ur_PK"}
+};
+
+ILCID_POSIX_SUBTABLE(uz) {
+    {0x43,   "uz"},
+    {0x0843, "uz_Cyrl_UZ"},  /* Cyrillic based */
+    {0x7843, "uz_Cyrl"},  /* Cyrillic based */
+    {0x0843, "uz_UZ"},  /* Cyrillic based */
+    {0x0443, "uz_Latn_UZ"}, /* Latin based */
+    {0x7c43, "uz_Latn"} /* Latin based */
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0433, ve, ve_ZA)    /* TODO: Verify the country */
+ILCID_POSIX_ELEMENT_ARRAY(0x042a, vi, vi_VN)
+
+ILCID_POSIX_SUBTABLE(wen) {
+    {0x2E,   "wen"},
+    {0x042E, "wen_DE"},
+    {0x042E, "hsb_DE"},
+    {0x082E, "dsb_DE"},
+    {0x7C2E, "dsb"},
+    {0x2E,   "hsb"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0488, wo, wo_SN)
+ILCID_POSIX_ELEMENT_ARRAY(0x0434, xh, xh_ZA)
+ILCID_POSIX_ELEMENT_ARRAY(0x046a, yo, yo_NG)
+
+ILCID_POSIX_SUBTABLE(zh) {
+    {0x0004, "zh_Hans"},
+    {0x7804, "zh"},
+    {0x0804, "zh_CN"},
+    {0x0804, "zh_Hans_CN"},
+    {0x0c04, "zh_Hant_HK"},
+    {0x0c04, "zh_HK"},
+    {0x1404, "zh_Hant_MO"},
+    {0x1404, "zh_MO"},
+    {0x1004, "zh_Hans_SG"},
+    {0x1004, "zh_SG"},
+    {0x0404, "zh_Hant_TW"},
+    {0x7c04, "zh_Hant"},
+    {0x0404, "zh_TW"},
+    {0x30404,"zh_Hant_TW"},     /* Bopomofo order */
+    {0x30404,"zh_TW"},          /* Bopomofo order */
+    {0x20404,"zh_Hant_TW@collation=stroke"},
+    {0x20404,"zh_TW@collation=stroke"},
+    {0x20804,"zh_Hans_CN@collation=stroke"},
+    {0x20804,"zh_CN@collation=stroke"}
+};
+
+ILCID_POSIX_ELEMENT_ARRAY(0x0435, zu, zu_ZA)
+
+/* This must be static and grouped by LCID. */
+
+/* non-existent ISO-639-2 codes */
+/*
+0x466   Edo
+0x467   Fulfulde - Nigeria
+0x486   K'iche - Guatemala
+0x430   Sutu
+*/
+static const ILcidPosixMap gPosixIDmap[] = {
+    ILCID_POSIX_MAP(af),    /*  af  Afrikaans                 0x36 */
+    ILCID_POSIX_MAP(am),    /*  am  Amharic                   0x5e */
+    ILCID_POSIX_MAP(ar),    /*  ar  Arabic                    0x01 */
+    ILCID_POSIX_MAP(arn),   /*  arn Araucanian/Mapudungun     0x7a */
+    ILCID_POSIX_MAP(as),    /*  as  Assamese                  0x4d */
+    ILCID_POSIX_MAP(az),    /*  az  Azerbaijani               0x2c */
+    ILCID_POSIX_MAP(ba),    /*  ba  Bashkir                   0x6d */
+    ILCID_POSIX_MAP(be),    /*  be  Belarusian                0x23 */
+/*    ILCID_POSIX_MAP(ber),     ber Berber/Tamazight          0x5f */
+    ILCID_POSIX_MAP(bg),    /*  bg  Bulgarian                 0x02 */
+    ILCID_POSIX_MAP(bn),    /*  bn  Bengali; Bangla           0x45 */
+    ILCID_POSIX_MAP(bo),    /*  bo  Tibetan                   0x51 */
+    ILCID_POSIX_MAP(br),    /*  br  Breton                    0x7e */
+    ILCID_POSIX_MAP(ca),    /*  ca  Catalan                   0x03 */
+    ILCID_POSIX_MAP(chr),   /*  chr Cherokee                  0x5c */
+    ILCID_POSIX_MAP(co),    /*  co  Corsican                  0x83 */
+    ILCID_POSIX_MAP(cs),    /*  cs  Czech                     0x05 */
+    ILCID_POSIX_MAP(cy),    /*  cy  Welsh                     0x52 */
+    ILCID_POSIX_MAP(da),    /*  da  Danish                    0x06 */
+    ILCID_POSIX_MAP(de),    /*  de  German                    0x07 */
+    ILCID_POSIX_MAP(dv),    /*  dv  Divehi                    0x65 */
+    ILCID_POSIX_MAP(el),    /*  el  Greek                     0x08 */
+    ILCID_POSIX_MAP(en),    /*  en  English                   0x09 */
+    ILCID_POSIX_MAP(en_US_POSIX), /*    invariant             0x7f */
+    ILCID_POSIX_MAP(es),    /*  es  Spanish                   0x0a */
+    ILCID_POSIX_MAP(et),    /*  et  Estonian                  0x25 */
+    ILCID_POSIX_MAP(eu),    /*  eu  Basque                    0x2d */
+    ILCID_POSIX_MAP(fa),    /*  fa  Persian/Farsi             0x29 */
+    ILCID_POSIX_MAP(fa_AF), /*  fa  Persian/Dari              0x8c */
+    ILCID_POSIX_MAP(fi),    /*  fi  Finnish                   0x0b */
+    ILCID_POSIX_MAP(fil),   /*  fil Filipino                  0x64 */
+    ILCID_POSIX_MAP(fo),    /*  fo  Faroese                   0x38 */
+    ILCID_POSIX_MAP(fr),    /*  fr  French                    0x0c */
+    ILCID_POSIX_MAP(fy),    /*  fy  Frisian                   0x62 */
+    ILCID_POSIX_MAP(ga),    /*  *   Gaelic (Ireland,Scotland) 0x3c */
+    ILCID_POSIX_MAP(gd),    /*  gd  Gaelic (United Kingdom)   0x91 */
+    ILCID_POSIX_MAP(gl),    /*  gl  Galician                  0x56 */
+    ILCID_POSIX_MAP(gn),    /*  gn  Guarani                   0x74 */
+    ILCID_POSIX_MAP(gsw),   /*  gsw Alemanic/Alsatian/Swiss German 0x84 */
+    ILCID_POSIX_MAP(gu),    /*  gu  Gujarati                  0x47 */
+    ILCID_POSIX_MAP(ha),    /*  ha  Hausa                     0x68 */
+    ILCID_POSIX_MAP(haw),   /*  haw Hawaiian                  0x75 */
+    ILCID_POSIX_MAP(he),    /*  he  Hebrew (formerly iw)      0x0d */
+    ILCID_POSIX_MAP(hi),    /*  hi  Hindi                     0x39 */
+    ILCID_POSIX_MAP(hr),    /*  *   Croatian and others       0x1a */
+    ILCID_POSIX_MAP(hu),    /*  hu  Hungarian                 0x0e */
+    ILCID_POSIX_MAP(hy),    /*  hy  Armenian                  0x2b */
+    ILCID_POSIX_MAP(id),    /*  id  Indonesian (formerly in)  0x21 */
+    ILCID_POSIX_MAP(ig),    /*  ig  Igbo                      0x70 */
+    ILCID_POSIX_MAP(ii),    /*  ii  Sichuan Yi                0x78 */
+    ILCID_POSIX_MAP(is),    /*  is  Icelandic                 0x0f */
+    ILCID_POSIX_MAP(it),    /*  it  Italian                   0x10 */
+    ILCID_POSIX_MAP(iu),    /*  iu  Inuktitut                 0x5d */
+    ILCID_POSIX_MAP(iw),    /*  iw  Hebrew                    0x0d */
+    ILCID_POSIX_MAP(ja),    /*  ja  Japanese                  0x11 */
+    ILCID_POSIX_MAP(ka),    /*  ka  Georgian                  0x37 */
+    ILCID_POSIX_MAP(kk),    /*  kk  Kazakh                    0x3f */
+    ILCID_POSIX_MAP(kl),    /*  kl  Kalaallisut               0x6f */
+    ILCID_POSIX_MAP(km),    /*  km  Khmer                     0x53 */
+    ILCID_POSIX_MAP(kn),    /*  kn  Kannada                   0x4b */
+    ILCID_POSIX_MAP(ko),    /*  ko  Korean                    0x12 */
+    ILCID_POSIX_MAP(kok),   /*  kok Konkani                   0x57 */
+    ILCID_POSIX_MAP(kr),    /*  kr  Kanuri                    0x71 */
+    ILCID_POSIX_MAP(ks),    /*  ks  Kashmiri                  0x60 */
+    ILCID_POSIX_MAP(ky),    /*  ky  Kyrgyz                    0x40 */
+    ILCID_POSIX_MAP(lb),    /*  lb  Luxembourgish             0x6e */
+    ILCID_POSIX_MAP(la),    /*  la  Latin                     0x76 */
+    ILCID_POSIX_MAP(lo),    /*  lo  Lao                       0x54 */
+    ILCID_POSIX_MAP(lt),    /*  lt  Lithuanian                0x27 */
+    ILCID_POSIX_MAP(lv),    /*  lv  Latvian, Lettish          0x26 */
+    ILCID_POSIX_MAP(mi),    /*  mi  Maori                     0x81 */
+    ILCID_POSIX_MAP(mk),    /*  mk  Macedonian                0x2f */
+    ILCID_POSIX_MAP(ml),    /*  ml  Malayalam                 0x4c */
+    ILCID_POSIX_MAP(mn),    /*  mn  Mongolian                 0x50 */
+    ILCID_POSIX_MAP(mni),   /*  mni Manipuri                  0x58 */
+    ILCID_POSIX_MAP(moh),   /*  moh Mohawk                    0x7c */
+    ILCID_POSIX_MAP(mr),    /*  mr  Marathi                   0x4e */
+    ILCID_POSIX_MAP(ms),    /*  ms  Malay                     0x3e */
+    ILCID_POSIX_MAP(mt),    /*  mt  Maltese                   0x3a */
+    ILCID_POSIX_MAP(my),    /*  my  Burmese                   0x55 */
+/*    ILCID_POSIX_MAP(nb),    //  no  Norwegian                 0x14 */
+    ILCID_POSIX_MAP(ne),    /*  ne  Nepali                    0x61 */
+    ILCID_POSIX_MAP(nl),    /*  nl  Dutch                     0x13 */
+/*    ILCID_POSIX_MAP(nn),    //  no  Norwegian                 0x14 */
+    ILCID_POSIX_MAP(no),    /*  *   Norwegian                 0x14 */
+    ILCID_POSIX_MAP(nso),   /*  nso Sotho, Northern (Sepedi dialect) 0x6c */
+    ILCID_POSIX_MAP(oc),    /*  oc  Occitan                   0x82 */
+    ILCID_POSIX_MAP(om),    /*  om  Oromo                     0x72 */
+    ILCID_POSIX_MAP(or_IN), /*  or  Oriya                     0x48 */
+    ILCID_POSIX_MAP(pa),    /*  pa  Punjabi                   0x46 */
+    ILCID_POSIX_MAP(pl),    /*  pl  Polish                    0x15 */
+    ILCID_POSIX_MAP(ps),    /*  ps  Pashto                    0x63 */
+    ILCID_POSIX_MAP(pt),    /*  pt  Portuguese                0x16 */
+    ILCID_POSIX_MAP(qu),    /*  qu  Quechua                   0x6B */
+    ILCID_POSIX_MAP(qut),   /*  qut K'iche                    0x86 */
+    ILCID_POSIX_MAP(rm),    /*  rm  Raeto-Romance/Romansh     0x17 */
+    ILCID_POSIX_MAP(ro),    /*  ro  Romanian                  0x18 */
+    ILCID_POSIX_MAP(root),  /*  root                          0x00 */
+    ILCID_POSIX_MAP(ru),    /*  ru  Russian                   0x19 */
+    ILCID_POSIX_MAP(rw),    /*  rw  Kinyarwanda               0x87 */
+    ILCID_POSIX_MAP(sa),    /*  sa  Sanskrit                  0x4f */
+    ILCID_POSIX_MAP(sah),   /*  sah Yakut                     0x85 */
+    ILCID_POSIX_MAP(sd),    /*  sd  Sindhi                    0x59 */
+    ILCID_POSIX_MAP(se),    /*  se  Sami                      0x3b */
+/*    ILCID_POSIX_MAP(sh),    //  sh  Serbo-Croatian            0x1a */
+    ILCID_POSIX_MAP(si),    /*  si  Sinhalese                 0x5b */
+    ILCID_POSIX_MAP(sk),    /*  sk  Slovak                    0x1b */
+    ILCID_POSIX_MAP(sl),    /*  sl  Slovenian                 0x24 */
+    ILCID_POSIX_MAP(so),    /*  so  Somali                    0x77 */
+    ILCID_POSIX_MAP(sq),    /*  sq  Albanian                  0x1c */
+/*    ILCID_POSIX_MAP(sr),    //  sr  Serbian                   0x1a */
+    ILCID_POSIX_MAP(sv),    /*  sv  Swedish                   0x1d */
+    ILCID_POSIX_MAP(sw),    /*  sw  Swahili                   0x41 */
+    ILCID_POSIX_MAP(syr),   /*  syr Syriac                    0x5A */
+    ILCID_POSIX_MAP(ta),    /*  ta  Tamil                     0x49 */
+    ILCID_POSIX_MAP(te),    /*  te  Telugu                    0x4a */
+    ILCID_POSIX_MAP(tg),    /*  tg  Tajik                     0x28 */
+    ILCID_POSIX_MAP(th),    /*  th  Thai                      0x1e */
+    ILCID_POSIX_MAP(ti),    /*  ti  Tigrigna                  0x73 */
+    ILCID_POSIX_MAP(tk),    /*  tk  Turkmen                   0x42 */
+    ILCID_POSIX_MAP(tn),    /*  tn  Tswana                    0x32 */
+    ILCID_POSIX_MAP(tr),    /*  tr  Turkish                   0x1f */
+    ILCID_POSIX_MAP(tt),    /*  tt  Tatar                     0x44 */
+    ILCID_POSIX_MAP(tzm),   /*  tzm                           0x5f */
+    ILCID_POSIX_MAP(ug),    /*  ug  Uighur                    0x80 */
+    ILCID_POSIX_MAP(uk),    /*  uk  Ukrainian                 0x22 */
+    ILCID_POSIX_MAP(ur),    /*  ur  Urdu                      0x20 */
+    ILCID_POSIX_MAP(uz),    /*  uz  Uzbek                     0x43 */
+    ILCID_POSIX_MAP(ve),    /*  ve  Venda                     0x33 */
+    ILCID_POSIX_MAP(vi),    /*  vi  Vietnamese                0x2a */
+    ILCID_POSIX_MAP(wen),   /*  wen Sorbian                   0x2e */
+    ILCID_POSIX_MAP(wo),    /*  wo  Wolof                     0x88 */
+    ILCID_POSIX_MAP(xh),    /*  xh  Xhosa                     0x34 */
+    ILCID_POSIX_MAP(yo),    /*  yo  Yoruba                    0x6a */
+    ILCID_POSIX_MAP(zh),    /*  zh  Chinese                   0x04 */
+    ILCID_POSIX_MAP(zu),    /*  zu  Zulu                      0x35 */
+};
+
+static const uint32_t gLocaleCount = sizeof(gPosixIDmap)/sizeof(ILcidPosixMap);
+
+/**
+ * Do not call this function. It is called by hostID.
+ * The function is not private because this struct must stay as a C struct,
+ * and this is an internal class.
+ */
+static int32_t
+idCmp(const char* id1, const char* id2)
+{
+    int32_t diffIdx = 0;
+    while (*id1 == *id2 && *id1 != 0) {
+        diffIdx++;
+        id1++;
+        id2++;
+    }
+    return diffIdx;
+}
+
+/**
+ * Searches for a Windows LCID
+ *
+ * @param posixid the Posix style locale id.
+ * @param status gets set to U_ILLEGAL_ARGUMENT_ERROR when the Posix ID has
+ *               no equivalent Windows LCID.
+ * @return the LCID
+ */
+static uint32_t
+getHostID(const ILcidPosixMap *this_0, const char* posixID, UErrorCode* status)
+{
+    int32_t bestIdx = 0;
+    int32_t bestIdxDiff = 0;
+    int32_t posixIDlen = (int32_t)uprv_strlen(posixID);
+    uint32_t idx;
+
+    for (idx = 0; idx < this_0->numRegions; idx++ ) {
+        int32_t sameChars = idCmp(posixID, this_0->regionMaps[idx].posixID);
+        if (sameChars > bestIdxDiff && this_0->regionMaps[idx].posixID[sameChars] == 0) {
+            if (posixIDlen == sameChars) {
+                /* Exact match */
+                return this_0->regionMaps[idx].hostID;
+            }
+            bestIdxDiff = sameChars;
+            bestIdx = idx;
+        }
+    }
+    /* We asked for something unusual, like en_ZZ, and we try to return the number for the same language. */
+    /* We also have to make sure that sid and si and similar string subsets don't match. */
+    if ((posixID[bestIdxDiff] == '_' || posixID[bestIdxDiff] == '@')
+        && this_0->regionMaps[bestIdx].posixID[bestIdxDiff] == 0)
+    {
+        *status = U_USING_FALLBACK_WARNING;
+        return this_0->regionMaps[bestIdx].hostID;
+    }
+
+    /*no match found */
+    *status = U_ILLEGAL_ARGUMENT_ERROR;
+    return this_0->regionMaps->hostID;
+}
+
+static const char*
+getPosixID(const ILcidPosixMap *this_0, uint32_t hostID)
+{
+    uint32_t i;
+    for (i = 0; i <= this_0->numRegions; i++)
+    {
+        if (this_0->regionMaps[i].hostID == hostID)
+        {
+            return this_0->regionMaps[i].posixID;
+        }
+    }
+
+    /* If you get here, then no matching region was found,
+       so return the language id with the wild card region. */
+    return this_0->regionMaps[0].posixID;
+}
+
+/*
+//////////////////////////////////////
+//
+// LCID --> POSIX
+//
+/////////////////////////////////////
+*/
+#ifdef USE_WINDOWS_LOCALE_API
+/*
+ * Change the tag separator from '-' to '_'
+ */
+#define FIX_LOCALE_ID_TAG_SEPARATOR(buffer, len, i) \
+    for(i = 0; i < len; i++) \
+        if (buffer[i] == '-') buffer[i] = '_';
+
+/*
+ * Various language tags needs to be changed:
+ * quz -> qu
+ * prs -> fa
+ */
+#define FIX_LANGUAGE_ID_TAG(buffer, len) \
+    if (len >= 3) { \
+        if (buffer[0] == 'q' && buffer[1] == 'u' && buffer[2] == 'z') {\
+            buffer[2] = 0; \
+            uprv_strcat(buffer, buffer+3); \
+        } else if (buffer[0] == 'p' && buffer[1] == 'r' && buffer[2] == 's') {\
+            buffer[0] = 'f'; buffer[1] = 'a'; buffer[2] = 0; \
+            uprv_strcat(buffer, buffer+3); \
+        } \
+    }
+
+static char gPosixFromLCID[ULOC_FULLNAME_CAPACITY];
+#endif
+U_CAPI const char *
+uprv_convertToPosix(uint32_t hostid, UErrorCode* status)
+{
+    uint16_t langID;
+    uint32_t localeIndex;
+#ifdef USE_WINDOWS_LOCALE_API
+    int32_t ret = 0;
+
+    uprv_memset(gPosixFromLCID, 0, sizeof(gPosixFromLCID));
+
+    ret = GetLocaleInfoA(hostid, LOCALE_SNAME, (LPSTR)gPosixFromLCID, sizeof(gPosixFromLCID));
+    if (ret > 1) {
+        FIX_LOCALE_ID_TAG_SEPARATOR(gPosixFromLCID, ret, localeIndex)
+        FIX_LANGUAGE_ID_TAG(gPosixFromLCID, ret)
+
+        return gPosixFromLCID;
+    }
+#endif
+    langID = LANGUAGE_LCID(hostid);
+
+    for (localeIndex = 0; localeIndex < gLocaleCount; localeIndex++)
+    {
+        if (langID == gPosixIDmap[localeIndex].regionMaps->hostID)
+        {
+            return getPosixID(&gPosixIDmap[localeIndex], hostid);
+        }
+    }
+
+    /* no match found */
+    *status = U_ILLEGAL_ARGUMENT_ERROR;
+    return NULL;
+}
+
+/*
+//////////////////////////////////////
+//
+// POSIX --> LCID
+// This should only be called from uloc_getLCID.
+// The locale ID must be in canonical form.
+// langID is separate so that this file doesn't depend on the uloc_* API.
+//
+/////////////////////////////////////
+*/
+
+U_CAPI uint32_t
+uprv_convertToLCID(const char *langID, const char* posixID, UErrorCode* status)
+{
+
+    uint32_t   low    = 0;
+    uint32_t   high   = gLocaleCount;
+    uint32_t   mid    = high;
+    uint32_t   oldmid = 0;
+    int32_t    compVal;
+
+    uint32_t   value         = 0;
+    uint32_t   fallbackValue = (uint32_t)-1;
+    UErrorCode myStatus;
+    uint32_t   idx;
+
+    /* Check for incomplete id. */
+    if (!langID || !posixID || uprv_strlen(langID) < 2 || uprv_strlen(posixID) < 2) {
+        return 0;
+    }
+
+    /*Binary search for the map entry for normal cases */
+
+    while (high > low)  /*binary search*/{
+
+        mid = (high+low) >> 1; /*Finds median*/
+
+        if (mid == oldmid) 
+            break;
+
+        compVal = uprv_strcmp(langID, gPosixIDmap[mid].regionMaps->posixID);
+        if (compVal < 0){
+            high = mid;
+        }
+        else if (compVal > 0){
+            low = mid;
+        }
+        else /*we found it*/{
+            return getHostID(&gPosixIDmap[mid], posixID, status);
+        }
+        oldmid = mid;
+    }
+
+    /*
+     * Sometimes we can't do a binary search on posixID because some LCIDs
+     * go to different locales.  We hit one of those special cases.
+     */
+    for (idx = 0; idx < gLocaleCount; idx++ ) {
+        myStatus = U_ZERO_ERROR;
+        value = getHostID(&gPosixIDmap[idx], posixID, &myStatus);
+        if (myStatus == U_ZERO_ERROR) {
+            return value;
+        }
+        else if (myStatus == U_USING_FALLBACK_WARNING) {
+            fallbackValue = value;
+        }
+    }
+
+    if (fallbackValue != (uint32_t)-1) {
+        *status = U_USING_FALLBACK_WARNING;
+        return fallbackValue;
+    }
+
+    /* no match found */
+    *status = U_ILLEGAL_ARGUMENT_ERROR;
+    return 0;   /* return international (root) */
+}
+
diff --git a/icu/source/common/locmap.h b/icu/source/common/locmap.h
new file mode 100644
index 0000000..7db0607
--- /dev/null
+++ b/icu/source/common/locmap.h
@@ -0,0 +1,37 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1996-2004, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+* File locmap.h      : Locale Mapping Classes
+* 
+*
+* Created by: Helena Shih
+*
+* Modification History:
+*
+*  Date        Name        Description
+*  3/11/97     aliu        Added setId().
+*  4/20/99     Madhu       Added T_convertToPosix()
+* 09/18/00     george      Removed the memory leaks.
+* 08/23/01     george      Convert to C
+*============================================================================
+*/
+
+#ifndef LOCMAP_H
+#define LOCMAP_H
+
+#include "unicode/utypes.h"
+
+#define LANGUAGE_LCID(hostID) (uint16_t)(0x03FF & hostID)
+
+U_CAPI const char *uprv_convertToPosix(uint32_t hostid, UErrorCode* status);
+
+/* Don't call this function directly. Use uloc_getLCID instead. */
+U_CAPI uint32_t uprv_convertToLCID(const char *langID, const char* posixID, UErrorCode* status);
+
+#endif /* LOCMAP_H */
+
diff --git a/icu/source/common/locresdata.cpp b/icu/source/common/locresdata.cpp
new file mode 100644
index 0000000..2c601c2
--- /dev/null
+++ b/icu/source/common/locresdata.cpp
@@ -0,0 +1,224 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 1997-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  loclikely.cpp
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2010feb25
+*   created by: Markus W. Scherer
+*
+*   Code for miscellaneous locale-related resource bundle data access,
+*   separated out from other .cpp files
+*   that then do not depend on resource bundle code and this data.
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/putil.h"
+#include "unicode/uloc.h"
+#include "unicode/ures.h"
+#include "cstring.h"
+#include "ulocimp.h"
+#include "uresimp.h"
+
+/*
+ * Lookup a resource bundle table item with fallback on the table level.
+ * Regular resource bundle lookups perform fallback to parent locale bundles
+ * and eventually the root bundle, but only for top-level items.
+ * This function takes the name of a top-level table and of an item in that table
+ * and performs a lookup of both, falling back until a bundle contains a table
+ * with this item.
+ *
+ * Note: Only the opening of entire bundles falls back through the default locale
+ * before root. Once a bundle is open, item lookups do not go through the
+ * default locale because that would result in a mix of languages that is
+ * unpredictable to the programmer and most likely useless.
+ */
+U_CAPI const UChar * U_EXPORT2
+uloc_getTableStringWithFallback(const char *path, const char *locale,
+                              const char *tableKey, const char *subTableKey,
+                              const char *itemKey,
+                              int32_t *pLength,
+                              UErrorCode *pErrorCode)
+{
+/*    char localeBuffer[ULOC_FULLNAME_CAPACITY*4];*/
+    UResourceBundle *rb=NULL, table, subTable;
+    const UChar *item=NULL;
+    UErrorCode errorCode;
+    char explicitFallbackName[ULOC_FULLNAME_CAPACITY] = {0};
+
+    /*
+     * open the bundle for the current locale
+     * this falls back through the locale's chain to root
+     */
+    errorCode=U_ZERO_ERROR;
+    rb=ures_open(path, locale, &errorCode);
+
+    if(U_FAILURE(errorCode)) {
+        /* total failure, not even root could be opened */
+        *pErrorCode=errorCode;
+        return NULL;
+    } else if(errorCode==U_USING_DEFAULT_WARNING ||
+                (errorCode==U_USING_FALLBACK_WARNING && *pErrorCode!=U_USING_DEFAULT_WARNING)
+    ) {
+        /* set the "strongest" error code (success->fallback->default->failure) */
+        *pErrorCode=errorCode;
+    }
+
+    for(;;){
+        ures_initStackObject(&table);
+        ures_initStackObject(&subTable);
+        ures_getByKeyWithFallback(rb, tableKey, &table, &errorCode);
+
+        if (subTableKey != NULL) {
+            /*
+            ures_getByKeyWithFallback(&table,subTableKey, &subTable, &errorCode);
+            item = ures_getStringByKeyWithFallback(&subTable, itemKey, pLength, &errorCode);
+            if(U_FAILURE(errorCode)){
+                *pErrorCode = errorCode;
+            }
+            
+            break;*/
+            
+            ures_getByKeyWithFallback(&table,subTableKey, &table, &errorCode);
+        }
+        if(U_SUCCESS(errorCode)){
+            item = ures_getStringByKeyWithFallback(&table, itemKey, pLength, &errorCode);
+            if(U_FAILURE(errorCode)){
+                const char* replacement = NULL;
+                *pErrorCode = errorCode; /*save the errorCode*/
+                errorCode = U_ZERO_ERROR;
+                /* may be a deprecated code */
+                if(uprv_strcmp(tableKey, "Countries")==0){
+                    replacement =  uloc_getCurrentCountryID(itemKey);
+                }else if(uprv_strcmp(tableKey, "Languages")==0){
+                    replacement =  uloc_getCurrentLanguageID(itemKey);
+                }
+                /*pointer comparison is ok since uloc_getCurrentCountryID & uloc_getCurrentLanguageID return the key itself is replacement is not found*/
+                if(replacement!=NULL && itemKey != replacement){
+                    item = ures_getStringByKeyWithFallback(&table, replacement, pLength, &errorCode);
+                    if(U_SUCCESS(errorCode)){
+                        *pErrorCode = errorCode;
+                        break;
+                    }
+                }
+            }else{
+                break;
+            }
+        }
+        
+        if(U_FAILURE(errorCode)){    
+
+            /* still can't figure out ?.. try the fallback mechanism */
+            int32_t len = 0;
+            const UChar* fallbackLocale =  NULL;
+            *pErrorCode = errorCode;
+            errorCode = U_ZERO_ERROR;
+
+            fallbackLocale = ures_getStringByKeyWithFallback(&table, "Fallback", &len, &errorCode);
+            if(U_FAILURE(errorCode)){
+               *pErrorCode = errorCode;
+                break;
+            }
+            
+            u_UCharsToChars(fallbackLocale, explicitFallbackName, len);
+            
+            /* guard against recursive fallback */
+            if(uprv_strcmp(explicitFallbackName, locale)==0){
+                *pErrorCode = U_INTERNAL_PROGRAM_ERROR;
+                break;
+            }
+            ures_close(rb);
+            rb = ures_open(path, explicitFallbackName, &errorCode);
+            if(U_FAILURE(errorCode)){
+                *pErrorCode = errorCode;
+                break;
+            }
+            /* succeeded in opening the fallback bundle .. continue and try to fetch the item */
+        }else{
+            break;
+        }
+    }
+    /* done with the locale string - ready to close table and rb */
+    ures_close(&subTable);
+    ures_close(&table);
+    ures_close(rb);
+    return item;
+}
+
+static ULayoutType
+_uloc_getOrientationHelper(const char* localeId,
+                           const char* key,
+                           UErrorCode *status)
+{
+    ULayoutType result = ULOC_LAYOUT_UNKNOWN;
+
+    if (!U_FAILURE(*status)) {
+        int32_t length = 0;
+        char localeBuffer[ULOC_FULLNAME_CAPACITY];
+
+        uloc_canonicalize(localeId, localeBuffer, sizeof(localeBuffer), status);
+
+        if (!U_FAILURE(*status)) {
+            const UChar* const value =
+                uloc_getTableStringWithFallback(
+                    NULL,
+                    localeBuffer,
+                    "layout",
+                    NULL,
+                    key,
+                    &length,
+                    status);
+
+            if (!U_FAILURE(*status) && length != 0) {
+                switch(value[0])
+                {
+                case 0x0062: /* 'b' */
+                    result = ULOC_LAYOUT_BTT;
+                    break;
+                case 0x006C: /* 'l' */
+                    result = ULOC_LAYOUT_LTR;
+                    break;
+                case 0x0072: /* 'r' */
+                    result = ULOC_LAYOUT_RTL;
+                    break;
+                case 0x0074: /* 't' */
+                    result = ULOC_LAYOUT_TTB;
+                    break;
+                default:
+                    *status = U_INTERNAL_PROGRAM_ERROR;
+                    break;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+U_DRAFT ULayoutType U_EXPORT2
+uloc_getCharacterOrientation(const char* localeId,
+                             UErrorCode *status)
+{
+    return _uloc_getOrientationHelper(localeId, "characters", status);
+}
+
+/**
+ * Get the layout line orientation for the specified locale.
+ * 
+ * @param localeID locale name
+ * @param status Error status
+ * @return an enum indicating the layout orientation for lines.
+ * @stable ICU 4.0
+ */
+U_DRAFT ULayoutType U_EXPORT2
+uloc_getLineOrientation(const char* localeId,
+                        UErrorCode *status)
+{
+    return _uloc_getOrientationHelper(localeId, "lines", status);
+}
diff --git a/icu/source/common/locutil.cpp b/icu/source/common/locutil.cpp
new file mode 100644
index 0000000..e70b616
--- /dev/null
+++ b/icu/source/common/locutil.cpp
@@ -0,0 +1,267 @@
+/**
+ *******************************************************************************
+ * Copyright (C) 2002-2006, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ *
+ *******************************************************************************
+ */
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_SERVICE || !UCONFIG_NO_TRANSLITERATION
+
+#include "unicode/resbund.h"
+#include "cmemory.h"
+#include "ustrfmt.h"
+#include "locutil.h"
+#include "charstr.h"
+#include "ucln_cmn.h"
+#include "uassert.h"
+#include "umutex.h"
+
+// see LocaleUtility::getAvailableLocaleNames
+static U_NAMESPACE_QUALIFIER Hashtable * LocaleUtility_cache = NULL;
+
+#define UNDERSCORE_CHAR ((UChar)0x005f)
+#define AT_SIGN_CHAR    ((UChar)64)
+#define PERIOD_CHAR     ((UChar)46)
+
+/*
+ ******************************************************************
+ */
+
+/**
+ * Release all static memory held by Locale Utility.  
+ */
+U_CDECL_BEGIN
+static UBool U_CALLCONV service_cleanup(void) {
+    if (LocaleUtility_cache) {
+        delete LocaleUtility_cache;
+        LocaleUtility_cache = NULL;
+    }
+    return TRUE;
+}
+U_CDECL_END
+
+U_NAMESPACE_BEGIN
+
+UnicodeString&
+LocaleUtility::canonicalLocaleString(const UnicodeString* id, UnicodeString& result)
+{
+  if (id == NULL) {
+    result.setToBogus();
+  } else {
+    // Fix case only (no other changes) up to the first '@' or '.' or
+    // end of string, whichever comes first.  In 3.0 I changed this to
+    // stop at first '@' or '.'.  It used to run out to the end of
+    // string.  My fix makes the tests pass but is probably
+    // structurally incorrect.  See below.  [alan 3.0]
+
+    // TODO: Doug, you might want to revise this...
+    result = *id;
+    int32_t i = 0;
+    int32_t end = result.indexOf(AT_SIGN_CHAR);
+    int32_t n = result.indexOf(PERIOD_CHAR);
+    if (n >= 0 && n < end) {
+        end = n;
+    }
+    if (end < 0) {
+        end = result.length();
+    }
+    n = result.indexOf(UNDERSCORE_CHAR);
+    if (n < 0) {
+      n = end;
+    }
+    for (; i < n; ++i) {
+      UChar c = result.charAt(i);
+      if (c >= 0x0041 && c <= 0x005a) {
+        c += 0x20;
+        result.setCharAt(i, c);
+      }
+    }
+    for (n = end; i < n; ++i) {
+      UChar c = result.charAt(i);
+      if (c >= 0x0061 && c <= 0x007a) {
+        c -= 0x20;
+        result.setCharAt(i, c);
+      }
+    }
+  }
+  return result;
+
+#if 0
+    // This code does a proper full level 2 canonicalization of id.
+    // It's nasty to go from UChar to char to char to UChar -- but
+    // that's what you have to do to use the uloc_canonicalize
+    // function on UnicodeStrings.
+
+    // I ended up doing the alternate fix (see above) not for
+    // performance reasons, although performance will certainly be
+    // better, but because doing a full level 2 canonicalization
+    // causes some tests to fail.  [alan 3.0]
+
+    // TODO: Doug, you might want to revisit this...
+    result.setToBogus();
+    if (id != 0) {
+        int32_t buflen = id->length() + 8; // space for NUL
+        char* buf = (char*) uprv_malloc(buflen);
+        char* canon = (buf == 0) ? 0 : (char*) uprv_malloc(buflen);
+        if (buf != 0 && canon != 0) {
+            U_ASSERT(id->extract(0, INT32_MAX, buf, buflen) < buflen);
+            UErrorCode ec = U_ZERO_ERROR;
+            uloc_canonicalize(buf, canon, buflen, &ec);
+            if (U_SUCCESS(ec)) {
+                result = UnicodeString(canon);
+            }
+        }
+        uprv_free(buf);
+        uprv_free(canon);
+    }
+    return result;
+#endif
+}
+
+Locale&
+LocaleUtility::initLocaleFromName(const UnicodeString& id, Locale& result)
+{
+    enum { BUFLEN = 128 }; // larger than ever needed
+
+    if (id.isBogus() || id.length() >= BUFLEN) {
+        result.setToBogus();
+    } else {
+        /*
+         * We need to convert from a UnicodeString to char * in order to
+         * create a Locale.
+         *
+         * Problem: Locale ID strings may contain '@' which is a variant
+         * character and cannot be handled by invariant-character conversion.
+         *
+         * Hack: Since ICU code can handle locale IDs with multiple encodings
+         * of '@' (at least for EBCDIC; it's not known to be a problem for
+         * ASCII-based systems),
+         * we use regular invariant-character conversion for everything else
+         * and manually convert U+0040 into a compiler-char-constant '@'.
+         * While this compilation-time constant may not match the runtime
+         * encoding of '@', it should be one of the encodings which ICU
+         * recognizes.
+         *
+         * There should be only at most one '@' in a locale ID.
+         */
+        char buffer[BUFLEN];
+        int32_t prev, i;
+        prev = 0;
+        for(;;) {
+            i = id.indexOf((UChar)0x40, prev);
+            if(i < 0) {
+                // no @ between prev and the rest of the string
+                id.extract(prev, INT32_MAX, buffer + prev, BUFLEN - prev, US_INV);
+                break; // done
+            } else {
+                // normal invariant-character conversion for text between @s
+                id.extract(prev, i - prev, buffer + prev, BUFLEN - prev, US_INV);
+                // manually "convert" U+0040 at id[i] into '@' at buffer[i]
+                buffer[i] = '@';
+                prev = i + 1;
+            }
+        }
+        result = Locale::createFromName(buffer);
+    }
+    return result;
+}
+
+UnicodeString&
+LocaleUtility::initNameFromLocale(const Locale& locale, UnicodeString& result)
+{
+    if (locale.isBogus()) {
+        result.setToBogus();
+    } else {
+        result.append(UnicodeString(locale.getName(), -1, US_INV));
+    }
+    return result;
+}
+
+const Hashtable*
+LocaleUtility::getAvailableLocaleNames(const UnicodeString& bundleID)
+{
+    // LocaleUtility_cache is a hash-of-hashes.  The top-level keys
+    // are path strings ('bundleID') passed to
+    // ures_openAvailableLocales.  The top-level values are
+    // second-level hashes.  The second-level keys are result strings
+    // from ures_openAvailableLocales.  The second-level values are
+    // garbage ((void*)1 or other random pointer).
+
+    UErrorCode status = U_ZERO_ERROR;
+    Hashtable* cache;
+    umtx_lock(NULL);
+    cache = LocaleUtility_cache;
+    umtx_unlock(NULL);
+
+    if (cache == NULL) {
+        cache = new Hashtable(status);
+        if (cache == NULL || U_FAILURE(status)) {
+            return NULL; // catastrophic failure; e.g. out of memory
+        }
+        cache->setValueDeleter(uhash_deleteHashtable);
+        Hashtable* h; // set this to final LocaleUtility_cache value
+        umtx_lock(NULL);
+        h = LocaleUtility_cache;
+        if (h == NULL) {
+            LocaleUtility_cache = h = cache;
+            cache = NULL;
+            ucln_common_registerCleanup(UCLN_COMMON_SERVICE, service_cleanup);
+        }
+        umtx_unlock(NULL);
+        if(cache != NULL) {
+          delete cache;
+        }
+        cache = h;
+    }
+
+    U_ASSERT(cache != NULL);
+
+    Hashtable* htp;
+    umtx_lock(NULL);
+    htp = (Hashtable*) cache->get(bundleID);
+    umtx_unlock(NULL);
+
+    if (htp == NULL) {
+        htp = new Hashtable(status);
+        if (htp && U_SUCCESS(status)) {
+            CharString cbundleID(bundleID);
+            const char* path = (const char*) cbundleID;
+            if (*path == 0) path = NULL; // empty string => NULL
+            UEnumeration *uenum = ures_openAvailableLocales(path, &status);
+            for (;;) {
+                const UChar* id = uenum_unext(uenum, NULL, &status);
+                if (id == NULL) {
+                    break;
+                }
+                htp->put(UnicodeString(id), (void*)htp, status);
+            }
+            uenum_close(uenum);
+            if (U_FAILURE(status)) {
+                delete htp;
+                return NULL;
+            }
+            umtx_lock(NULL);
+            cache->put(bundleID, (void*)htp, status);
+            umtx_unlock(NULL);
+        }
+    }
+    return htp;
+}
+
+UBool
+LocaleUtility::isFallbackOf(const UnicodeString& root, const UnicodeString& child)
+{
+    return child.indexOf(root) == 0 &&
+      (child.length() == root.length() ||
+       child.charAt(root.length()) == UNDERSCORE_CHAR);
+}
+
+U_NAMESPACE_END
+
+/* !UCONFIG_NO_SERVICE */
+#endif
+
+
diff --git a/icu/source/common/locutil.h b/icu/source/common/locutil.h
new file mode 100644
index 0000000..cf64e34
--- /dev/null
+++ b/icu/source/common/locutil.h
@@ -0,0 +1,37 @@
+/**
+ *******************************************************************************
+ * Copyright (C) 2002-2005, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ *
+ *******************************************************************************
+ */
+#ifndef LOCUTIL_H
+#define LOCUTIL_H
+
+#include "unicode/utypes.h"
+#include "hash.h"
+
+#if !UCONFIG_NO_SERVICE || !UCONFIG_NO_TRANSLITERATION
+
+
+U_NAMESPACE_BEGIN
+
+// temporary utility functions, till I know where to find them
+// in header so tests can also access them
+
+class U_COMMON_API LocaleUtility {
+public:
+  static UnicodeString& canonicalLocaleString(const UnicodeString* id, UnicodeString& result);
+  static Locale& initLocaleFromName(const UnicodeString& id, Locale& result);
+  static UnicodeString& initNameFromLocale(const Locale& locale, UnicodeString& result);
+  static const Hashtable* getAvailableLocaleNames(const UnicodeString& bundleID);
+  static UBool isFallbackOf(const UnicodeString& root, const UnicodeString& child);
+};
+
+U_NAMESPACE_END
+
+
+#endif
+
+#endif
diff --git a/icu/source/common/msvcres.h b/icu/source/common/msvcres.h
new file mode 100644
index 0000000..7ed61b4
--- /dev/null
+++ b/icu/source/common/msvcres.h
@@ -0,0 +1,23 @@
+//{{NO_DEPENDENCIES}}
+// Copyright (c) 2003-2010 International Business Machines
+// Corporation and others. All Rights Reserved.
+//
+// Used by common.rc and other .rc files.
+//Do not edit with Microsoft Developer Studio because it will modify this
+//header the wrong way. This is here to prevent Visual Studio .NET from
+//unnessarily building the resource files when it's not needed.
+//
+
+/*
+These are defined before unicode/uversion.h in order to prevent 
+STLPort's broken stddef.h from being used when rc.exe parses this file. 
+*/
+#define _STLP_OUTERMOST_HEADER_ID 0
+#define _STLP_WINCE 1
+
+#include "unicode/uversion.h"
+
+#define ICU_WEBSITE "http://icu-project.org"
+#define ICU_COMPANY "The ICU Project"
+#define ICU_PRODUCT_PREFIX "ICU"
+#define ICU_PRODUCT "International Components for Unicode"
diff --git a/icu/source/common/mutex.cpp b/icu/source/common/mutex.cpp
new file mode 100644
index 0000000..8da3c7e
--- /dev/null
+++ b/icu/source/common/mutex.cpp
@@ -0,0 +1,91 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2008-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  mutex.cpp
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*/
+
+#include "unicode/utypes.h"
+#include "mutex.h"
+
+U_NAMESPACE_BEGIN
+
+void *SimpleSingleton::getInstance(InstantiatorFn *instantiator, const void *context,
+                                   void *&duplicate,
+                                   UErrorCode &errorCode) {
+    duplicate=NULL;
+    if(U_FAILURE(errorCode)) {
+        return NULL;
+    }
+    void *instance;
+    UMTX_CHECK(NULL, fInstance, instance);
+    if(instance!=NULL) {
+        return instance;
+    } else {
+        instance=instantiator(context, errorCode);
+        Mutex mutex;
+        if(fInstance==NULL && U_SUCCESS(errorCode)) {
+            fInstance=instance;
+        } else {
+            duplicate=instance;
+        }
+        return fInstance;
+    }
+}
+
+void *TriStateSingleton::getInstance(InstantiatorFn *instantiator, const void *context,
+                                     void *&duplicate,
+                                     UErrorCode &errorCode) {
+    duplicate=NULL;
+    if(U_FAILURE(errorCode)) {
+        return NULL;
+    }
+    int8_t haveInstance;
+    UMTX_CHECK(NULL, fHaveInstance, haveInstance);
+    if(haveInstance>0) {
+        return fInstance;  // instance was created
+    } else if(haveInstance<0) {
+        errorCode=fErrorCode;  // instance creation failed
+        return NULL;
+    } else /* haveInstance==0 */ {
+        void *instance=instantiator(context, errorCode);
+        Mutex mutex;
+        if(fHaveInstance==0) {
+            if(U_SUCCESS(errorCode)) {
+                fInstance=instance;
+                instance=NULL;
+                fHaveInstance=1;
+            } else {
+                fErrorCode=errorCode;
+                fHaveInstance=-1;
+            }
+        } else {
+            errorCode=fErrorCode;
+        }
+        duplicate=instance;
+        return fInstance;
+    }
+}
+
+void TriStateSingleton::reset() {
+    fInstance=NULL;
+    fErrorCode=U_ZERO_ERROR;
+    fHaveInstance=0;
+}
+
+#if UCONFIG_NO_SERVICE
+
+/* If UCONFIG_NO_SERVICE, then there is no invocation of Mutex elsewhere in
+   common, so add one here to force an export */
+static Mutex *aMutex = 0;
+
+/* UCONFIG_NO_SERVICE */
+#endif
+
+U_NAMESPACE_END
diff --git a/icu/source/common/mutex.h b/icu/source/common/mutex.h
new file mode 100644
index 0000000..ea2e348
--- /dev/null
+++ b/icu/source/common/mutex.h
@@ -0,0 +1,199 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1997-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*/
+//----------------------------------------------------------------------------
+// File:     mutex.h
+//
+// Lightweight C++ wrapper for umtx_ C mutex functions
+//
+// Author:   Alan Liu  1/31/97
+// History:
+// 06/04/97   helena         Updated setImplementation as per feedback from 5/21 drop.
+// 04/07/1999  srl               refocused as a thin wrapper
+//
+//----------------------------------------------------------------------------
+#ifndef MUTEX_H
+#define MUTEX_H
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+#include "umutex.h"
+
+U_NAMESPACE_BEGIN
+
+//----------------------------------------------------------------------------
+// Code within that accesses shared static or global data should
+// should instantiate a Mutex object while doing so. You should make your own 
+// private mutex where possible.
+
+// For example:
+// 
+// UMTX myMutex;
+// 
+// void Function(int arg1, int arg2)
+// {
+//    static Object* foo;     // Shared read-write object
+//    Mutex mutex(&myMutex);  // or no args for the global lock
+//    foo->Method();
+//    // When 'mutex' goes out of scope and gets destroyed here, the lock is released
+// }
+//
+// Note:  Do NOT use the form 'Mutex mutex();' as that merely forward-declares a function
+//        returning a Mutex. This is a common mistake which silently slips through the
+//        compiler!!
+//
+
+class U_COMMON_API Mutex : public UMemory {
+public:
+  inline Mutex(UMTX *mutex = NULL);
+  inline ~Mutex();
+
+private:
+  UMTX   *fMutex;
+
+  Mutex(const Mutex &other); // forbid copying of this class
+  Mutex &operator=(const Mutex &other); // forbid copying of this class
+};
+
+inline Mutex::Mutex(UMTX *mutex)
+  : fMutex(mutex)
+{
+  umtx_lock(fMutex);
+}
+
+inline Mutex::~Mutex()
+{
+  umtx_unlock(fMutex);
+}
+
+// common code for singletons ---------------------------------------------- ***
+
+/**
+ * Function pointer for the instantiator parameter of
+ * SimpleSingleton::getInstance() and TriStateSingleton::getInstance().
+ * The function creates some object, optionally using the context parameter.
+ * The function need not check for U_FAILURE(errorCode).
+ */
+typedef void *InstantiatorFn(const void *context, UErrorCode &errorCode);
+
+/**
+ * Singleton struct with shared instantiation/mutexing code.
+ * Simple: Does not remember if a previous instantiation failed.
+ * Best used if the instantiation can really only fail with an out-of-memory error,
+ * otherwise use a TriStateSingleton.
+ * Best used via SimpleSingletonWrapper or similar.
+ * Define a static SimpleSingleton instance via the STATIC_SIMPLE_SINGLETON macro.
+ */
+struct SimpleSingleton {
+    void *fInstance;
+
+    /**
+     * Returns the singleton instance, or NULL if it could not be created.
+     * Calls the instantiator with the context if the instance has not been
+     * created yet. In a race condition, the duplicate may not be NULL.
+     * The caller must delete the duplicate.
+     * The caller need not initialize the duplicate before the call.
+     */
+    void *getInstance(InstantiatorFn *instantiator, const void *context,
+                      void *&duplicate,
+                      UErrorCode &errorCode);
+    /**
+     * Resets the fields. The caller must have deleted the singleton instance.
+     * Not mutexed.
+     * Call this from a cleanup function.
+     */
+    void reset() { fInstance=NULL; }
+};
+
+#define STATIC_SIMPLE_SINGLETON(name) static SimpleSingleton name={ NULL }
+
+/**
+ * Handy wrapper for an SimpleSingleton.
+ * Intended for temporary use on the stack, to make the SimpleSingleton easier to deal with.
+ * Takes care of the duplicate deletion and type casting.
+ */
+template<typename T>
+class SimpleSingletonWrapper {
+public:
+    SimpleSingletonWrapper(SimpleSingleton &s) : singleton(s) {}
+    void deleteInstance() {
+        delete (T *)singleton.fInstance;
+        singleton.reset();
+    }
+    T *getInstance(InstantiatorFn *instantiator, const void *context,
+                   UErrorCode &errorCode) {
+        void *duplicate;
+        T *instance=(T *)singleton.getInstance(instantiator, context, duplicate, errorCode);
+        delete (T *)duplicate;
+        return instance;
+    }
+private:
+    SimpleSingleton &singleton;
+};
+
+/**
+ * Singleton struct with shared instantiation/mutexing code.
+ * Tri-state: Instantiation succeeded/failed/not attempted yet.
+ * Best used via TriStateSingletonWrapper or similar.
+ * Define a static TriStateSingleton instance via the STATIC_TRI_STATE_SINGLETON macro.
+ */
+struct TriStateSingleton {
+    void *fInstance;
+    UErrorCode fErrorCode;
+    int8_t fHaveInstance;
+
+    /**
+     * Returns the singleton instance, or NULL if it could not be created.
+     * Calls the instantiator with the context if the instance has not been
+     * created yet. In a race condition, the duplicate may not be NULL.
+     * The caller must delete the duplicate.
+     * The caller need not initialize the duplicate before the call.
+     * The singleton creation is only attempted once. If it fails,
+     * the singleton will then always return NULL.
+     */
+    void *getInstance(InstantiatorFn *instantiator, const void *context,
+                      void *&duplicate,
+                      UErrorCode &errorCode);
+    /**
+     * Resets the fields. The caller must have deleted the singleton instance.
+     * Not mutexed.
+     * Call this from a cleanup function.
+     */
+    void reset();
+};
+
+#define STATIC_TRI_STATE_SINGLETON(name) static TriStateSingleton name={ NULL, U_ZERO_ERROR, 0 }
+
+/**
+ * Handy wrapper for an TriStateSingleton.
+ * Intended for temporary use on the stack, to make the TriStateSingleton easier to deal with.
+ * Takes care of the duplicate deletion and type casting.
+ */
+template<typename T>
+class TriStateSingletonWrapper {
+public:
+    TriStateSingletonWrapper(TriStateSingleton &s) : singleton(s) {}
+    void deleteInstance() {
+        delete (T *)singleton.fInstance;
+        singleton.reset();
+    }
+    T *getInstance(InstantiatorFn *instantiator, const void *context,
+                   UErrorCode &errorCode) {
+        void *duplicate;
+        T *instance=(T *)singleton.getInstance(instantiator, context, duplicate, errorCode);
+        delete (T *)duplicate;
+        return instance;
+    }
+private:
+    TriStateSingleton &singleton;
+};
+
+U_NAMESPACE_END
+
+#endif //_MUTEX_
+//eof
diff --git a/icu/source/common/normalizer2.cpp b/icu/source/common/normalizer2.cpp
new file mode 100644
index 0000000..5678ce5
--- /dev/null
+++ b/icu/source/common/normalizer2.cpp
@@ -0,0 +1,809 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2009-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  normalizer2.cpp
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2009nov22
+*   created by: Markus W. Scherer
+*/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_NORMALIZATION
+
+#include "unicode/localpointer.h"
+#include "unicode/normalizer2.h"
+#include "unicode/unistr.h"
+#include "unicode/unorm.h"
+#include "cpputils.h"
+#include "cstring.h"
+#include "mutex.h"
+#include "normalizer2impl.h"
+#include "ucln_cmn.h"
+#include "uhash.h"
+
+U_NAMESPACE_BEGIN
+
+// Public API dispatch via Normalizer2 subclasses -------------------------- ***
+
+// Normalizer2 implementation for the old UNORM_NONE.
+class NoopNormalizer2 : public Normalizer2 {
+    virtual UnicodeString &
+    normalize(const UnicodeString &src,
+              UnicodeString &dest,
+              UErrorCode &errorCode) const {
+        if(U_SUCCESS(errorCode)) {
+            if(&dest!=&src) {
+                dest=src;
+            } else {
+                errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+            }
+        }
+        return dest;
+    }
+    virtual UnicodeString &
+    normalizeSecondAndAppend(UnicodeString &first,
+                             const UnicodeString &second,
+                             UErrorCode &errorCode) const {
+        if(U_SUCCESS(errorCode)) {
+            if(&first!=&second) {
+                first.append(second);
+            } else {
+                errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+            }
+        }
+        return first;
+    }
+    virtual UnicodeString &
+    append(UnicodeString &first,
+           const UnicodeString &second,
+           UErrorCode &errorCode) const {
+        if(U_SUCCESS(errorCode)) {
+            if(&first!=&second) {
+                first.append(second);
+            } else {
+                errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+            }
+        }
+        return first;
+    }
+    virtual UBool
+    isNormalized(const UnicodeString &, UErrorCode &) const {
+        return TRUE;
+    }
+    virtual UNormalizationCheckResult
+    quickCheck(const UnicodeString &, UErrorCode &) const {
+        return UNORM_YES;
+    }
+    virtual int32_t
+    spanQuickCheckYes(const UnicodeString &s, UErrorCode &) const {
+        return s.length();
+    }
+    virtual UBool hasBoundaryBefore(UChar32) const { return TRUE; }
+    virtual UBool hasBoundaryAfter(UChar32) const { return TRUE; }
+    virtual UBool isInert(UChar32) const { return TRUE; }
+
+    static UClassID U_EXPORT2 getStaticClassID();
+    virtual UClassID getDynamicClassID() const;
+};
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(NoopNormalizer2)
+
+// Intermediate class:
+// Has Normalizer2Impl and does boilerplate argument checking and setup.
+class Normalizer2WithImpl : public Normalizer2 {
+public:
+    Normalizer2WithImpl(const Normalizer2Impl &ni) : impl(ni) {}
+
+    // normalize
+    virtual UnicodeString &
+    normalize(const UnicodeString &src,
+              UnicodeString &dest,
+              UErrorCode &errorCode) const {
+        if(U_FAILURE(errorCode)) {
+            dest.setToBogus();
+            return dest;
+        }
+        const UChar *sArray=src.getBuffer();
+        if(&dest==&src || sArray==NULL) {
+            errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+            dest.setToBogus();
+            return dest;
+        }
+        dest.remove();
+        ReorderingBuffer buffer(impl, dest);
+        if(buffer.init(src.length(), errorCode)) {
+            normalize(sArray, sArray+src.length(), buffer, errorCode);
+        }
+        return dest;
+    }
+    virtual void
+    normalize(const UChar *src, const UChar *limit,
+              ReorderingBuffer &buffer, UErrorCode &errorCode) const = 0;
+
+    // normalize and append
+    virtual UnicodeString &
+    normalizeSecondAndAppend(UnicodeString &first,
+                             const UnicodeString &second,
+                             UErrorCode &errorCode) const {
+        return normalizeSecondAndAppend(first, second, TRUE, errorCode);
+    }
+    virtual UnicodeString &
+    append(UnicodeString &first,
+           const UnicodeString &second,
+           UErrorCode &errorCode) const {
+        return normalizeSecondAndAppend(first, second, FALSE, errorCode);
+    }
+    UnicodeString &
+    normalizeSecondAndAppend(UnicodeString &first,
+                             const UnicodeString &second,
+                             UBool doNormalize,
+                             UErrorCode &errorCode) const {
+        uprv_checkCanGetBuffer(first, errorCode);
+        if(U_FAILURE(errorCode)) {
+            return first;
+        }
+        const UChar *secondArray=second.getBuffer();
+        if(&first==&second || secondArray==NULL) {
+            errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+            return first;
+        }
+        ReorderingBuffer buffer(impl, first);
+        if(buffer.init(first.length()+second.length(), errorCode)) {
+            normalizeAndAppend(secondArray, secondArray+second.length(), doNormalize,
+                               buffer, errorCode);
+        }
+        return first;
+    }
+    virtual void
+    normalizeAndAppend(const UChar *src, const UChar *limit, UBool doNormalize,
+                       ReorderingBuffer &buffer, UErrorCode &errorCode) const = 0;
+
+    // quick checks
+    virtual UBool
+    isNormalized(const UnicodeString &s, UErrorCode &errorCode) const {
+        if(U_FAILURE(errorCode)) {
+            return FALSE;
+        }
+        const UChar *sArray=s.getBuffer();
+        if(sArray==NULL) {
+            errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+            return FALSE;
+        }
+        const UChar *sLimit=sArray+s.length();
+        return sLimit==spanQuickCheckYes(sArray, sLimit, errorCode);
+    }
+    virtual UNormalizationCheckResult
+    quickCheck(const UnicodeString &s, UErrorCode &errorCode) const {
+        return Normalizer2WithImpl::isNormalized(s, errorCode) ? UNORM_YES : UNORM_NO;
+    }
+    virtual int32_t
+    spanQuickCheckYes(const UnicodeString &s, UErrorCode &errorCode) const {
+        if(U_FAILURE(errorCode)) {
+            return 0;
+        }
+        const UChar *sArray=s.getBuffer();
+        if(sArray==NULL) {
+            errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+            return 0;
+        }
+        return (int32_t)(spanQuickCheckYes(sArray, sArray+s.length(), errorCode)-sArray);
+    }
+    virtual const UChar *
+    spanQuickCheckYes(const UChar *src, const UChar *limit, UErrorCode &errorCode) const = 0;
+
+    virtual UNormalizationCheckResult getQuickCheck(UChar32) const {
+        return UNORM_YES;
+    }
+
+    static UClassID U_EXPORT2 getStaticClassID();
+    virtual UClassID getDynamicClassID() const;
+
+    const Normalizer2Impl &impl;
+};
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Normalizer2WithImpl)
+
+class DecomposeNormalizer2 : public Normalizer2WithImpl {
+public:
+    DecomposeNormalizer2(const Normalizer2Impl &ni) : Normalizer2WithImpl(ni) {}
+
+private:
+    virtual void
+    normalize(const UChar *src, const UChar *limit,
+              ReorderingBuffer &buffer, UErrorCode &errorCode) const {
+        impl.decompose(src, limit, &buffer, errorCode);
+    }
+    using Normalizer2WithImpl::normalize;  // Avoid warning about hiding base class function.
+    virtual void
+    normalizeAndAppend(const UChar *src, const UChar *limit, UBool doNormalize,
+                       ReorderingBuffer &buffer, UErrorCode &errorCode) const {
+        impl.decomposeAndAppend(src, limit, doNormalize, buffer, errorCode);
+    }
+    virtual const UChar *
+    spanQuickCheckYes(const UChar *src, const UChar *limit, UErrorCode &errorCode) const {
+        return impl.decompose(src, limit, NULL, errorCode);
+    }
+    using Normalizer2WithImpl::spanQuickCheckYes;  // Avoid warning about hiding base class function.
+    virtual UNormalizationCheckResult getQuickCheck(UChar32 c) const {
+        return impl.isDecompYes(impl.getNorm16(c)) ? UNORM_YES : UNORM_NO;
+    }
+    virtual UBool hasBoundaryBefore(UChar32 c) const { return impl.hasDecompBoundary(c, TRUE); }
+    virtual UBool hasBoundaryAfter(UChar32 c) const { return impl.hasDecompBoundary(c, FALSE); }
+    virtual UBool isInert(UChar32 c) const { return impl.isDecompInert(c); }
+};
+
+class ComposeNormalizer2 : public Normalizer2WithImpl {
+public:
+    ComposeNormalizer2(const Normalizer2Impl &ni, UBool fcc) :
+        Normalizer2WithImpl(ni), onlyContiguous(fcc) {}
+
+private:
+    virtual void
+    normalize(const UChar *src, const UChar *limit,
+              ReorderingBuffer &buffer, UErrorCode &errorCode) const {
+        impl.compose(src, limit, onlyContiguous, TRUE, buffer, errorCode);
+    }
+    using Normalizer2WithImpl::normalize;  // Avoid warning about hiding base class function.
+    virtual void
+    normalizeAndAppend(const UChar *src, const UChar *limit, UBool doNormalize,
+                       ReorderingBuffer &buffer, UErrorCode &errorCode) const {
+        impl.composeAndAppend(src, limit, doNormalize, onlyContiguous, buffer, errorCode);
+    }
+
+    virtual UBool
+    isNormalized(const UnicodeString &s, UErrorCode &errorCode) const {
+        if(U_FAILURE(errorCode)) {
+            return FALSE;
+        }
+        const UChar *sArray=s.getBuffer();
+        if(sArray==NULL) {
+            errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+            return FALSE;
+        }
+        UnicodeString temp;
+        ReorderingBuffer buffer(impl, temp);
+        if(!buffer.init(5, errorCode)) {  // small destCapacity for substring normalization
+            return FALSE;
+        }
+        return impl.compose(sArray, sArray+s.length(), onlyContiguous, FALSE, buffer, errorCode);
+    }
+    virtual UNormalizationCheckResult
+    quickCheck(const UnicodeString &s, UErrorCode &errorCode) const {
+        if(U_FAILURE(errorCode)) {
+            return UNORM_MAYBE;
+        }
+        const UChar *sArray=s.getBuffer();
+        if(sArray==NULL) {
+            errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+            return UNORM_MAYBE;
+        }
+        UNormalizationCheckResult qcResult=UNORM_YES;
+        impl.composeQuickCheck(sArray, sArray+s.length(), onlyContiguous, &qcResult);
+        return qcResult;
+    }
+    virtual const UChar *
+    spanQuickCheckYes(const UChar *src, const UChar *limit, UErrorCode &) const {
+        return impl.composeQuickCheck(src, limit, onlyContiguous, NULL);
+    }
+    using Normalizer2WithImpl::spanQuickCheckYes;  // Avoid warning about hiding base class function.
+    virtual UNormalizationCheckResult getQuickCheck(UChar32 c) const {
+        return impl.getCompQuickCheck(impl.getNorm16(c));
+    }
+    virtual UBool hasBoundaryBefore(UChar32 c) const {
+        return impl.hasCompBoundaryBefore(c);
+    }
+    virtual UBool hasBoundaryAfter(UChar32 c) const {
+        return impl.hasCompBoundaryAfter(c, onlyContiguous, FALSE);
+    }
+    virtual UBool isInert(UChar32 c) const {
+        return impl.hasCompBoundaryAfter(c, onlyContiguous, TRUE);
+    }
+
+    const UBool onlyContiguous;
+};
+
+class FCDNormalizer2 : public Normalizer2WithImpl {
+public:
+    FCDNormalizer2(const Normalizer2Impl &ni) : Normalizer2WithImpl(ni) {}
+
+private:
+    virtual void
+    normalize(const UChar *src, const UChar *limit,
+              ReorderingBuffer &buffer, UErrorCode &errorCode) const {
+        impl.makeFCD(src, limit, &buffer, errorCode);
+    }
+    using Normalizer2WithImpl::normalize;  // Avoid warning about hiding base class function.
+    virtual void
+    normalizeAndAppend(const UChar *src, const UChar *limit, UBool doNormalize,
+                       ReorderingBuffer &buffer, UErrorCode &errorCode) const {
+        impl.makeFCDAndAppend(src, limit, doNormalize, buffer, errorCode);
+    }
+    virtual const UChar *
+    spanQuickCheckYes(const UChar *src, const UChar *limit, UErrorCode &errorCode) const {
+        return impl.makeFCD(src, limit, NULL, errorCode);
+    }
+    using Normalizer2WithImpl::spanQuickCheckYes;  // Avoid warning about hiding base class function.
+    virtual UBool hasBoundaryBefore(UChar32 c) const { return impl.hasFCDBoundaryBefore(c); }
+    virtual UBool hasBoundaryAfter(UChar32 c) const { return impl.hasFCDBoundaryAfter(c); }
+    virtual UBool isInert(UChar32 c) const { return impl.isFCDInert(c); }
+};
+
+// instance cache ---------------------------------------------------------- ***
+
+struct Norm2AllModes : public UMemory {
+    static Norm2AllModes *createInstance(const char *packageName,
+                                         const char *name,
+                                         UErrorCode &errorCode);
+    Norm2AllModes() : comp(impl, FALSE), decomp(impl), fcd(impl), fcc(impl, TRUE) {}
+
+    Normalizer2Impl impl;
+    ComposeNormalizer2 comp;
+    DecomposeNormalizer2 decomp;
+    FCDNormalizer2 fcd;
+    ComposeNormalizer2 fcc;
+};
+
+Norm2AllModes *
+Norm2AllModes::createInstance(const char *packageName,
+                              const char *name,
+                              UErrorCode &errorCode) {
+    if(U_FAILURE(errorCode)) {
+        return NULL;
+    }
+    LocalPointer<Norm2AllModes> allModes(new Norm2AllModes);
+    if(allModes.isNull()) {
+        errorCode=U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
+    }
+    allModes->impl.load(packageName, name, errorCode);
+    return U_SUCCESS(errorCode) ? allModes.orphan() : NULL;
+}
+
+U_CDECL_BEGIN
+static UBool U_CALLCONV uprv_normalizer2_cleanup();
+U_CDECL_END
+
+class Norm2AllModesSingleton : public TriStateSingletonWrapper<Norm2AllModes> {
+public:
+    Norm2AllModesSingleton(TriStateSingleton &s, const char *n) :
+        TriStateSingletonWrapper<Norm2AllModes>(s), name(n) {}
+    Norm2AllModes *getInstance(UErrorCode &errorCode) {
+        return TriStateSingletonWrapper<Norm2AllModes>::getInstance(createInstance, name, errorCode);
+    }
+private:
+    static void *createInstance(const void *context, UErrorCode &errorCode) {
+        ucln_common_registerCleanup(UCLN_COMMON_NORMALIZER2, uprv_normalizer2_cleanup);
+        return Norm2AllModes::createInstance(NULL, (const char *)context, errorCode);
+    }
+
+    const char *name;
+};
+
+STATIC_TRI_STATE_SINGLETON(nfcSingleton);
+STATIC_TRI_STATE_SINGLETON(nfkcSingleton);
+STATIC_TRI_STATE_SINGLETON(nfkc_cfSingleton);
+
+class Norm2Singleton : public SimpleSingletonWrapper<Normalizer2> {
+public:
+    Norm2Singleton(SimpleSingleton &s) : SimpleSingletonWrapper<Normalizer2>(s) {}
+    Normalizer2 *getInstance(UErrorCode &errorCode) {
+        return SimpleSingletonWrapper<Normalizer2>::getInstance(createInstance, NULL, errorCode);
+    }
+private:
+    static void *createInstance(const void *, UErrorCode &errorCode) {
+        Normalizer2 *noop=new NoopNormalizer2;
+        if(noop==NULL) {
+            errorCode=U_MEMORY_ALLOCATION_ERROR;
+        }
+        ucln_common_registerCleanup(UCLN_COMMON_NORMALIZER2, uprv_normalizer2_cleanup);
+        return noop;
+    }
+};
+
+STATIC_SIMPLE_SINGLETON(noopSingleton);
+
+static UHashtable *cache=NULL;
+
+U_CDECL_BEGIN
+
+static void U_CALLCONV deleteNorm2AllModes(void *allModes) {
+    delete (Norm2AllModes *)allModes;
+}
+
+static UBool U_CALLCONV uprv_normalizer2_cleanup() {
+    Norm2AllModesSingleton(nfcSingleton, NULL).deleteInstance();
+    Norm2AllModesSingleton(nfkcSingleton, NULL).deleteInstance();
+    Norm2AllModesSingleton(nfkc_cfSingleton, NULL).deleteInstance();
+    Norm2Singleton(noopSingleton).deleteInstance();
+    uhash_close(cache);
+    cache=NULL;
+    return TRUE;
+}
+
+U_CDECL_END
+
+const Normalizer2 *Normalizer2Factory::getNFCInstance(UErrorCode &errorCode) {
+    Norm2AllModes *allModes=Norm2AllModesSingleton(nfcSingleton, "nfc").getInstance(errorCode);
+    return allModes!=NULL ? &allModes->comp : NULL;
+}
+
+const Normalizer2 *Normalizer2Factory::getNFDInstance(UErrorCode &errorCode) {
+    Norm2AllModes *allModes=Norm2AllModesSingleton(nfcSingleton, "nfc").getInstance(errorCode);
+    return allModes!=NULL ? &allModes->decomp : NULL;
+}
+
+const Normalizer2 *Normalizer2Factory::getFCDInstance(UErrorCode &errorCode) {
+    Norm2AllModes *allModes=Norm2AllModesSingleton(nfcSingleton, "nfc").getInstance(errorCode);
+    if(allModes!=NULL) {
+        allModes->impl.getFCDTrie(errorCode);
+        return &allModes->fcd;
+    } else {
+        return NULL;
+    }
+}
+
+const Normalizer2 *Normalizer2Factory::getFCCInstance(UErrorCode &errorCode) {
+    Norm2AllModes *allModes=Norm2AllModesSingleton(nfcSingleton, "nfc").getInstance(errorCode);
+    return allModes!=NULL ? &allModes->fcc : NULL;
+}
+
+const Normalizer2 *Normalizer2Factory::getNFKCInstance(UErrorCode &errorCode) {
+    Norm2AllModes *allModes=
+        Norm2AllModesSingleton(nfkcSingleton, "nfkc").getInstance(errorCode);
+    return allModes!=NULL ? &allModes->comp : NULL;
+}
+
+const Normalizer2 *Normalizer2Factory::getNFKDInstance(UErrorCode &errorCode) {
+    Norm2AllModes *allModes=
+        Norm2AllModesSingleton(nfkcSingleton, "nfkc").getInstance(errorCode);
+    return allModes!=NULL ? &allModes->decomp : NULL;
+}
+
+const Normalizer2 *Normalizer2Factory::getNFKC_CFInstance(UErrorCode &errorCode) {
+    Norm2AllModes *allModes=
+        Norm2AllModesSingleton(nfkc_cfSingleton, "nfkc_cf").getInstance(errorCode);
+    return allModes!=NULL ? &allModes->comp : NULL;
+}
+
+const Normalizer2 *Normalizer2Factory::getNoopInstance(UErrorCode &errorCode) {
+    return Norm2Singleton(noopSingleton).getInstance(errorCode);
+}
+
+const Normalizer2 *
+Normalizer2Factory::getInstance(UNormalizationMode mode, UErrorCode &errorCode) {
+    if(U_FAILURE(errorCode)) {
+        return NULL;
+    }
+    switch(mode) {
+    case UNORM_NFD:
+        return getNFDInstance(errorCode);
+    case UNORM_NFKD:
+        return getNFKDInstance(errorCode);
+    case UNORM_NFC:
+        return getNFCInstance(errorCode);
+    case UNORM_NFKC:
+        return getNFKCInstance(errorCode);
+    case UNORM_FCD:
+        return getFCDInstance(errorCode);
+    default:  // UNORM_NONE
+        return getNoopInstance(errorCode);
+    }
+}
+
+const Normalizer2Impl *
+Normalizer2Factory::getNFCImpl(UErrorCode &errorCode) {
+    Norm2AllModes *allModes=
+        Norm2AllModesSingleton(nfcSingleton, "nfc").getInstance(errorCode);
+    return allModes!=NULL ? &allModes->impl : NULL;
+}
+
+const Normalizer2Impl *
+Normalizer2Factory::getNFKCImpl(UErrorCode &errorCode) {
+    Norm2AllModes *allModes=
+        Norm2AllModesSingleton(nfkcSingleton, "nfkc").getInstance(errorCode);
+    return allModes!=NULL ? &allModes->impl : NULL;
+}
+
+const Normalizer2Impl *
+Normalizer2Factory::getNFKC_CFImpl(UErrorCode &errorCode) {
+    Norm2AllModes *allModes=
+        Norm2AllModesSingleton(nfkc_cfSingleton, "nfkc_cf").getInstance(errorCode);
+    return allModes!=NULL ? &allModes->impl : NULL;
+}
+
+const Normalizer2Impl *
+Normalizer2Factory::getImpl(const Normalizer2 *norm2) {
+    return &((Normalizer2WithImpl *)norm2)->impl;
+}
+
+const UTrie2 *
+Normalizer2Factory::getFCDTrie(UErrorCode &errorCode) {
+    Norm2AllModes *allModes=
+        Norm2AllModesSingleton(nfcSingleton, "nfc").getInstance(errorCode);
+    if(allModes!=NULL) {
+        return allModes->impl.getFCDTrie(errorCode);
+    } else {
+        return NULL;
+    }
+}
+
+const Normalizer2 *
+Normalizer2::getInstance(const char *packageName,
+                         const char *name,
+                         UNormalization2Mode mode,
+                         UErrorCode &errorCode) {
+    if(U_FAILURE(errorCode)) {
+        return NULL;
+    }
+    if(name==NULL || *name==0) {
+        errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+    }
+    Norm2AllModes *allModes=NULL;
+    if(packageName==NULL) {
+        if(0==uprv_strcmp(name, "nfc")) {
+            allModes=Norm2AllModesSingleton(nfcSingleton, "nfc").getInstance(errorCode);
+        } else if(0==uprv_strcmp(name, "nfkc")) {
+            allModes=Norm2AllModesSingleton(nfkcSingleton, "nfkc").getInstance(errorCode);
+        } else if(0==uprv_strcmp(name, "nfkc_cf")) {
+            allModes=Norm2AllModesSingleton(nfkc_cfSingleton, "nfkc_cf").getInstance(errorCode);
+        }
+    }
+    if(allModes==NULL && U_SUCCESS(errorCode)) {
+        {
+            Mutex lock;
+            if(cache!=NULL) {
+                allModes=(Norm2AllModes *)uhash_get(cache, name);
+            }
+        }
+        if(allModes==NULL) {
+            LocalPointer<Norm2AllModes> localAllModes(
+                Norm2AllModes::createInstance(packageName, name, errorCode));
+            if(U_SUCCESS(errorCode)) {
+                Mutex lock;
+                if(cache==NULL) {
+                    cache=uhash_open(uhash_hashChars, uhash_compareChars, NULL, &errorCode);
+                    if(U_FAILURE(errorCode)) {
+                        return NULL;
+                    }
+                    uhash_setKeyDeleter(cache, uprv_free);
+                    uhash_setValueDeleter(cache, deleteNorm2AllModes);
+                }
+                void *temp=uhash_get(cache, name);
+                if(temp==NULL) {
+                    int32_t keyLength=uprv_strlen(name)+1;
+                    char *nameCopy=(char *)uprv_malloc(keyLength);
+                    if(nameCopy==NULL) {
+                        errorCode=U_MEMORY_ALLOCATION_ERROR;
+                        return NULL;
+                    }
+                    uprv_memcpy(nameCopy, name, keyLength);
+                    uhash_put(cache, nameCopy, allModes=localAllModes.orphan(), &errorCode);
+                } else {
+                    // race condition
+                    allModes=(Norm2AllModes *)temp;
+                }
+            }
+        }
+    }
+    if(allModes!=NULL && U_SUCCESS(errorCode)) {
+        switch(mode) {
+        case UNORM2_COMPOSE:
+            return &allModes->comp;
+        case UNORM2_DECOMPOSE:
+            return &allModes->decomp;
+        case UNORM2_FCD:
+            allModes->impl.getFCDTrie(errorCode);
+            return &allModes->fcd;
+        case UNORM2_COMPOSE_CONTIGUOUS:
+            return &allModes->fcc;
+        default:
+            break;  // do nothing
+        }
+    }
+    return NULL;
+}
+
+UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(Normalizer2)
+
+U_NAMESPACE_END
+
+// C API ------------------------------------------------------------------- ***
+
+U_NAMESPACE_USE
+
+U_DRAFT const UNormalizer2 * U_EXPORT2
+unorm2_getInstance(const char *packageName,
+                   const char *name,
+                   UNormalization2Mode mode,
+                   UErrorCode *pErrorCode) {
+    return (const UNormalizer2 *)Normalizer2::getInstance(packageName, name, mode, *pErrorCode);
+}
+
+U_DRAFT void U_EXPORT2
+unorm2_close(UNormalizer2 *norm2) {
+    delete (Normalizer2 *)norm2;
+}
+
+U_DRAFT int32_t U_EXPORT2
+unorm2_normalize(const UNormalizer2 *norm2,
+                 const UChar *src, int32_t length,
+                 UChar *dest, int32_t capacity,
+                 UErrorCode *pErrorCode) {
+    if(U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+    if(src==NULL || length<-1 || capacity<0 || (dest==NULL && capacity>0) || src==dest) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    UnicodeString destString(dest, 0, capacity);
+    const Normalizer2 *n2=(const Normalizer2 *)norm2;
+    if(n2->getDynamicClassID()==Normalizer2WithImpl::getStaticClassID()) {
+        // Avoid duplicate argument checking and support NUL-terminated src.
+        const Normalizer2WithImpl *n2wi=(const Normalizer2WithImpl *)n2;
+        ReorderingBuffer buffer(n2wi->impl, destString);
+        if(buffer.init(length, *pErrorCode)) {
+            n2wi->normalize(src, length>=0 ? src+length : NULL, buffer, *pErrorCode);
+        }
+    } else {
+        UnicodeString srcString(length<0, src, length);
+        n2->normalize(srcString, destString, *pErrorCode);
+    }
+    return destString.extract(dest, capacity, *pErrorCode);
+}
+
+static int32_t
+normalizeSecondAndAppend(const UNormalizer2 *norm2,
+                         UChar *first, int32_t firstLength, int32_t firstCapacity,
+                         const UChar *second, int32_t secondLength,
+                         UBool doNormalize,
+                         UErrorCode *pErrorCode) {
+    if(U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+    if( second==NULL || secondLength<-1 ||
+        firstCapacity<0 || (first==NULL && firstCapacity>0) || firstLength<-1 ||
+        first==second
+    ) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    UnicodeString firstString(first, firstLength, firstCapacity);
+    const Normalizer2 *n2=(const Normalizer2 *)norm2;
+    if(n2->getDynamicClassID()==Normalizer2WithImpl::getStaticClassID()) {
+        // Avoid duplicate argument checking and support NUL-terminated src.
+        const Normalizer2WithImpl *n2wi=(const Normalizer2WithImpl *)n2;
+        ReorderingBuffer buffer(n2wi->impl, firstString);
+        if(buffer.init(firstLength+secondLength+1, *pErrorCode)) {  // destCapacity>=-1
+            n2wi->normalizeAndAppend(second, secondLength>=0 ? second+secondLength : NULL,
+                                     doNormalize, buffer, *pErrorCode);
+        }
+    } else {
+        UnicodeString secondString(secondLength<0, second, secondLength);
+        if(doNormalize) {
+            n2->normalizeSecondAndAppend(firstString, secondString, *pErrorCode);
+        } else {
+            n2->append(firstString, secondString, *pErrorCode);
+        }
+    }
+    return firstString.extract(first, firstCapacity, *pErrorCode);
+}
+
+U_DRAFT int32_t U_EXPORT2
+unorm2_normalizeSecondAndAppend(const UNormalizer2 *norm2,
+                                UChar *first, int32_t firstLength, int32_t firstCapacity,
+                                const UChar *second, int32_t secondLength,
+                                UErrorCode *pErrorCode) {
+    return normalizeSecondAndAppend(norm2,
+                                    first, firstLength, firstCapacity,
+                                    second, secondLength,
+                                    TRUE, pErrorCode);
+}
+
+U_DRAFT int32_t U_EXPORT2
+unorm2_append(const UNormalizer2 *norm2,
+              UChar *first, int32_t firstLength, int32_t firstCapacity,
+              const UChar *second, int32_t secondLength,
+              UErrorCode *pErrorCode) {
+    return normalizeSecondAndAppend(norm2,
+                                    first, firstLength, firstCapacity,
+                                    second, secondLength,
+                                    FALSE, pErrorCode);
+}
+
+U_DRAFT UBool U_EXPORT2
+unorm2_isNormalized(const UNormalizer2 *norm2,
+                    const UChar *s, int32_t length,
+                    UErrorCode *pErrorCode) {
+    if(U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+    if(s==NULL || length<-1) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    UnicodeString sString(length<0, s, length);
+    return ((const Normalizer2 *)norm2)->isNormalized(sString, *pErrorCode);
+}
+
+U_DRAFT UNormalizationCheckResult U_EXPORT2
+unorm2_quickCheck(const UNormalizer2 *norm2,
+                  const UChar *s, int32_t length,
+                  UErrorCode *pErrorCode) {
+    if(U_FAILURE(*pErrorCode)) {
+        return UNORM_NO;
+    }
+    if(s==NULL || length<-1) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return UNORM_NO;
+    }
+    UnicodeString sString(length<0, s, length);
+    return ((const Normalizer2 *)norm2)->quickCheck(sString, *pErrorCode);
+}
+
+U_DRAFT int32_t U_EXPORT2
+unorm2_spanQuickCheckYes(const UNormalizer2 *norm2,
+                         const UChar *s, int32_t length,
+                         UErrorCode *pErrorCode) {
+    if(U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+    if(s==NULL || length<-1) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    UnicodeString sString(length<0, s, length);
+    return ((const Normalizer2 *)norm2)->spanQuickCheckYes(sString, *pErrorCode);
+}
+
+U_DRAFT UBool U_EXPORT2
+unorm2_hasBoundaryBefore(const UNormalizer2 *norm2, UChar32 c) {
+    return ((const Normalizer2 *)norm2)->hasBoundaryBefore(c);
+}
+
+U_DRAFT UBool U_EXPORT2
+unorm2_hasBoundaryAfter(const UNormalizer2 *norm2, UChar32 c) {
+    return ((const Normalizer2 *)norm2)->hasBoundaryAfter(c);
+}
+
+U_DRAFT UBool U_EXPORT2
+unorm2_isInert(const UNormalizer2 *norm2, UChar32 c) {
+    return ((const Normalizer2 *)norm2)->isInert(c);
+}
+
+// Some properties APIs ---------------------------------------------------- ***
+
+U_CFUNC UNormalizationCheckResult U_EXPORT2
+unorm_getQuickCheck(UChar32 c, UNormalizationMode mode) {
+    if(mode<=UNORM_NONE || UNORM_FCD<=mode) {
+        return UNORM_YES;
+    }
+    UErrorCode errorCode=U_ZERO_ERROR;
+    const Normalizer2 *norm2=Normalizer2Factory::getInstance(mode, errorCode);
+    if(U_SUCCESS(errorCode)) {
+        return ((const Normalizer2WithImpl *)norm2)->getQuickCheck(c);
+    } else {
+        return UNORM_MAYBE;
+    }
+}
+
+U_CAPI const uint16_t * U_EXPORT2
+unorm_getFCDTrieIndex(UChar32 &fcdHighStart, UErrorCode *pErrorCode) {
+    const UTrie2 *trie=Normalizer2Factory::getFCDTrie(*pErrorCode);
+    if(U_SUCCESS(*pErrorCode)) {
+        fcdHighStart=trie->highStart;
+        return trie->index;
+    } else {
+        return NULL;
+    }
+}
+
+#endif  // !UCONFIG_NO_NORMALIZATION
diff --git a/icu/source/common/normalizer2impl.cpp b/icu/source/common/normalizer2impl.cpp
new file mode 100644
index 0000000..48ceb12
--- /dev/null
+++ b/icu/source/common/normalizer2impl.cpp
@@ -0,0 +1,1733 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2009-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  normalizer2impl.cpp
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2009nov22
+*   created by: Markus W. Scherer
+*/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_NORMALIZATION
+
+#include "unicode/normalizer2.h"
+#include "unicode/udata.h"
+#include "unicode/ustring.h"
+#include "cmemory.h"
+#include "mutex.h"
+#include "normalizer2impl.h"
+#include "uassert.h"
+#include "uset_imp.h"
+#include "utrie2.h"
+
+U_NAMESPACE_BEGIN
+
+// ReorderingBuffer -------------------------------------------------------- ***
+
+UBool ReorderingBuffer::init(int32_t destCapacity, UErrorCode &errorCode) {
+    int32_t length=str.length();
+    start=str.getBuffer(destCapacity);
+    if(start==NULL) {
+        // getBuffer() already did str.setToBogus()
+        errorCode=U_MEMORY_ALLOCATION_ERROR;
+        return FALSE;
+    }
+    limit=start+length;
+    remainingCapacity=str.getCapacity()-length;
+    reorderStart=start;
+    if(start==limit) {
+        lastCC=0;
+    } else {
+        setIterator();
+        lastCC=previousCC();
+        // Set reorderStart after the last code point with cc<=1 if there is one.
+        if(lastCC>1) {
+            while(previousCC()>1) {}
+        }
+        reorderStart=codePointLimit;
+    }
+    return TRUE;
+}
+
+UBool ReorderingBuffer::equals(const UChar *otherStart, const UChar *otherLimit) const {
+    int32_t length=(int32_t)(limit-start);
+    return
+        length==(int32_t)(otherLimit-otherStart) &&
+        0==u_memcmp(start, otherStart, length);
+}
+
+UBool ReorderingBuffer::appendSupplementary(UChar32 c, uint8_t cc, UErrorCode &errorCode) {
+    if(remainingCapacity<2 && !resize(2, errorCode)) {
+        return FALSE;
+    }
+    if(lastCC<=cc || cc==0) {
+        limit[0]=U16_LEAD(c);
+        limit[1]=U16_TRAIL(c);
+        limit+=2;
+        lastCC=cc;
+        if(cc<=1) {
+            reorderStart=limit;
+        }
+    } else {
+        insert(c, cc);
+    }
+    remainingCapacity-=2;
+    return TRUE;
+}
+
+UBool ReorderingBuffer::append(const UChar *s, int32_t length,
+                               uint8_t leadCC, uint8_t trailCC,
+                               UErrorCode &errorCode) {
+    if(length==0) {
+        return TRUE;
+    }
+    if(remainingCapacity<length && !resize(length, errorCode)) {
+        return FALSE;
+    }
+    remainingCapacity-=length;
+    if(lastCC<=leadCC || leadCC==0) {
+        if(trailCC<=1) {
+            reorderStart=limit+length;
+        } else if(leadCC<=1) {
+            reorderStart=limit+1;  // Ok if not a code point boundary.
+        }
+        const UChar *sLimit=s+length;
+        do { *limit++=*s++; } while(s!=sLimit);
+        lastCC=trailCC;
+    } else {
+        int32_t i=0;
+        UChar32 c;
+        U16_NEXT(s, i, length, c);
+        insert(c, leadCC);  // insert first code point
+        while(i<length) {
+            U16_NEXT(s, i, length, c);
+            if(i<length) {
+                // s must be in NFD, otherwise we need to use getCC().
+                leadCC=Normalizer2Impl::getCCFromYesOrMaybe(impl.getNorm16(c));
+            } else {
+                leadCC=trailCC;
+            }
+            append(c, leadCC, errorCode);
+        }
+    }
+    return TRUE;
+}
+
+UBool ReorderingBuffer::appendZeroCC(UChar32 c, UErrorCode &errorCode) {
+    int32_t cpLength=U16_LENGTH(c);
+    if(remainingCapacity<cpLength && !resize(cpLength, errorCode)) {
+        return FALSE;
+    }
+    remainingCapacity-=cpLength;
+    if(cpLength==1) {
+        *limit++=(UChar)c;
+    } else {
+        limit[0]=U16_LEAD(c);
+        limit[1]=U16_TRAIL(c);
+        limit+=2;
+    }
+    lastCC=0;
+    reorderStart=limit;
+    return TRUE;
+}
+
+UBool ReorderingBuffer::appendZeroCC(const UChar *s, const UChar *sLimit, UErrorCode &errorCode) {
+    if(s==sLimit) {
+        return TRUE;
+    }
+    int32_t length=(int32_t)(sLimit-s);
+    if(remainingCapacity<length && !resize(length, errorCode)) {
+        return FALSE;
+    }
+    u_memcpy(limit, s, length);
+    limit+=length;
+    remainingCapacity-=length;
+    lastCC=0;
+    reorderStart=limit;
+    return TRUE;
+}
+
+void ReorderingBuffer::remove() {
+    reorderStart=limit=start;
+    remainingCapacity=str.getCapacity();
+    lastCC=0;
+}
+
+void ReorderingBuffer::removeSuffix(int32_t suffixLength) {
+    if(suffixLength<(limit-start)) {
+        limit-=suffixLength;
+        remainingCapacity+=suffixLength;
+    } else {
+        limit=start;
+        remainingCapacity=str.getCapacity();
+    }
+    lastCC=0;
+    reorderStart=limit;
+}
+
+UBool ReorderingBuffer::resize(int32_t appendLength, UErrorCode &errorCode) {
+    int32_t reorderStartIndex=(int32_t)(reorderStart-start);
+    int32_t length=(int32_t)(limit-start);
+    str.releaseBuffer(length);
+    int32_t newCapacity=length+appendLength;
+    int32_t doubleCapacity=2*str.getCapacity();
+    if(newCapacity<doubleCapacity) {
+        newCapacity=doubleCapacity;
+    }
+    if(newCapacity<256) {
+        newCapacity=256;
+    }
+    start=str.getBuffer(newCapacity);
+    if(start==NULL) {
+        // getBuffer() already did str.setToBogus()
+        errorCode=U_MEMORY_ALLOCATION_ERROR;
+        return FALSE;
+    }
+    reorderStart=start+reorderStartIndex;
+    limit=start+length;
+    remainingCapacity=str.getCapacity()-length;
+    return TRUE;
+}
+
+void ReorderingBuffer::skipPrevious() {
+    codePointLimit=codePointStart;
+    UChar c=*--codePointStart;
+    if(U16_IS_TRAIL(c) && start<codePointStart && U16_IS_LEAD(*(codePointStart-1))) {
+        --codePointStart;
+    }
+}
+
+uint8_t ReorderingBuffer::previousCC() {
+    codePointLimit=codePointStart;
+    if(reorderStart>=codePointStart) {
+        return 0;
+    }
+    UChar32 c=*--codePointStart;
+    if(c<Normalizer2Impl::MIN_CCC_LCCC_CP) {
+        return 0;
+    }
+
+    UChar c2;
+    if(U16_IS_TRAIL(c) && start<codePointStart && U16_IS_LEAD(c2=*(codePointStart-1))) {
+        --codePointStart;
+        c=U16_GET_SUPPLEMENTARY(c2, c);
+    }
+    return Normalizer2Impl::getCCFromYesOrMaybe(impl.getNorm16(c));
+}
+
+// Inserts c somewhere before the last character.
+// Requires 0<cc<lastCC which implies reorderStart<limit.
+void ReorderingBuffer::insert(UChar32 c, uint8_t cc) {
+    for(setIterator(), skipPrevious(); previousCC()>cc;) {}
+    // insert c at codePointLimit, after the character with prevCC<=cc
+    UChar *q=limit;
+    UChar *r=limit+=U16_LENGTH(c);
+    do {
+        *--r=*--q;
+    } while(codePointLimit!=q);
+    writeCodePoint(q, c);
+    if(cc<=1) {
+        reorderStart=r;
+    }
+}
+
+// Normalizer2Impl --------------------------------------------------------- ***
+
+Normalizer2Impl::~Normalizer2Impl() {
+    udata_close(memory);
+    utrie2_close(normTrie);
+    UTrie2Singleton(fcdTrieSingleton).deleteInstance();
+}
+
+UBool U_CALLCONV
+Normalizer2Impl::isAcceptable(void *context,
+                              const char *type, const char *name,
+                              const UDataInfo *pInfo) {
+    if(
+        pInfo->size>=20 &&
+        pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
+        pInfo->charsetFamily==U_CHARSET_FAMILY &&
+        pInfo->dataFormat[0]==0x4e &&    /* dataFormat="Nrm2" */
+        pInfo->dataFormat[1]==0x72 &&
+        pInfo->dataFormat[2]==0x6d &&
+        pInfo->dataFormat[3]==0x32 &&
+        pInfo->formatVersion[0]==1
+    ) {
+        Normalizer2Impl *me=(Normalizer2Impl *)context;
+        uprv_memcpy(me->dataVersion, pInfo->dataVersion, 4);
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+
+void
+Normalizer2Impl::load(const char *packageName, const char *name, UErrorCode &errorCode) {
+    if(U_FAILURE(errorCode)) {
+        return;
+    }
+    memory=udata_openChoice(packageName, "nrm", name, isAcceptable, this, &errorCode);
+    if(U_FAILURE(errorCode)) {
+        return;
+    }
+    const uint8_t *inBytes=(const uint8_t *)udata_getMemory(memory);
+    const int32_t *inIndexes=(const int32_t *)inBytes;
+    int32_t indexesLength=inIndexes[IX_NORM_TRIE_OFFSET]/4;
+    if(indexesLength<=IX_MIN_MAYBE_YES) {
+        errorCode=U_INVALID_FORMAT_ERROR;  // Not enough indexes.
+        return;
+    }
+
+    minDecompNoCP=inIndexes[IX_MIN_DECOMP_NO_CP];
+    minCompNoMaybeCP=inIndexes[IX_MIN_COMP_NO_MAYBE_CP];
+
+    minYesNo=inIndexes[IX_MIN_YES_NO];
+    minNoNo=inIndexes[IX_MIN_NO_NO];
+    limitNoNo=inIndexes[IX_LIMIT_NO_NO];
+    minMaybeYes=inIndexes[IX_MIN_MAYBE_YES];
+
+    int32_t offset=inIndexes[IX_NORM_TRIE_OFFSET];
+    int32_t nextOffset=inIndexes[IX_EXTRA_DATA_OFFSET];
+    normTrie=utrie2_openFromSerialized(UTRIE2_16_VALUE_BITS,
+                                       inBytes+offset, nextOffset-offset, NULL,
+                                       &errorCode);
+    if(U_FAILURE(errorCode)) {
+        return;
+    }
+
+    offset=nextOffset;
+    maybeYesCompositions=(const uint16_t *)(inBytes+offset);
+    extraData=maybeYesCompositions+(MIN_NORMAL_MAYBE_YES-minMaybeYes);
+}
+
+uint8_t Normalizer2Impl::getTrailCCFromCompYesAndZeroCC(const UChar *cpStart, const UChar *cpLimit) const {
+    UChar32 c;
+    if(cpStart==(cpLimit-1)) {
+        c=*cpStart;
+    } else {
+        c=U16_GET_SUPPLEMENTARY(cpStart[0], cpStart[1]);
+    }
+    uint16_t prevNorm16=getNorm16(c);
+    if(prevNorm16<=minYesNo) {
+        return 0;  // yesYes and Hangul LV/LVT have ccc=tccc=0
+    } else {
+        return (uint8_t)(*getMapping(prevNorm16)>>8);  // tccc from yesNo
+    }
+}
+
+U_CDECL_BEGIN
+
+static UBool U_CALLCONV
+enumPropertyStartsRange(const void *context, UChar32 start, UChar32 /*end*/, uint32_t /*value*/) {
+    /* add the start code point to the USet */
+    const USetAdder *sa=(const USetAdder *)context;
+    sa->add(sa->set, start);
+    return TRUE;
+}
+
+U_CDECL_END
+
+void
+Normalizer2Impl::addPropertyStarts(const USetAdder *sa, UErrorCode &errorCode) const {
+    /* add the start code point of each same-value range of each trie */
+    utrie2_enum(normTrie, NULL, enumPropertyStartsRange, sa);
+
+    /* add Hangul LV syllables and LV+1 because of skippables */
+    for(UChar c=Hangul::HANGUL_BASE; c<Hangul::HANGUL_LIMIT; c+=Hangul::JAMO_T_COUNT) {
+        sa->add(sa->set, c);
+        sa->add(sa->set, c+1);
+    }
+    sa->add(sa->set, Hangul::HANGUL_LIMIT); /* add Hangul+1 to continue with other properties */
+}
+
+const UChar *
+Normalizer2Impl::copyLowPrefixFromNulTerminated(const UChar *src,
+                                                UChar32 minNeedDataCP,
+                                                ReorderingBuffer *buffer,
+                                                UErrorCode &errorCode) const {
+    // Make some effort to support NUL-terminated strings reasonably.
+    // Take the part of the fast quick check loop that does not look up
+    // data and check the first part of the string.
+    // After this prefix, determine the string length to simplify the rest
+    // of the code.
+    const UChar *prevSrc=src;
+    UChar c;
+    while((c=*src++)<minNeedDataCP && c!=0) {}
+    // Back out the last character for full processing.
+    // Copy this prefix.
+    if(--src!=prevSrc) {
+        if(buffer!=NULL) {
+            buffer->appendZeroCC(prevSrc, src, errorCode);
+        }
+    }
+    return src;
+}
+
+// Dual functionality:
+// buffer!=NULL: normalize
+// buffer==NULL: isNormalized/spanQuickCheckYes
+const UChar *
+Normalizer2Impl::decompose(const UChar *src, const UChar *limit,
+                           ReorderingBuffer *buffer,
+                           UErrorCode &errorCode) const {
+    UChar32 minNoCP=minDecompNoCP;
+    if(limit==NULL) {
+        src=copyLowPrefixFromNulTerminated(src, minNoCP, buffer, errorCode);
+        if(U_FAILURE(errorCode)) {
+            return src;
+        }
+        limit=u_strchr(src, 0);
+    }
+
+    const UChar *prevSrc;
+    UChar32 c=0;
+    uint16_t norm16=0;
+
+    // only for quick check
+    const UChar *prevBoundary=src;
+    uint8_t prevCC=0;
+
+    for(;;) {
+        // count code units below the minimum or with irrelevant data for the quick check
+        for(prevSrc=src; src!=limit;) {
+            if( (c=*src)<minNoCP ||
+                isMostDecompYesAndZeroCC(norm16=UTRIE2_GET16_FROM_U16_SINGLE_LEAD(normTrie, c))
+            ) {
+                ++src;
+            } else if(!U16_IS_SURROGATE(c)) {
+                break;
+            } else {
+                UChar c2;
+                if(U16_IS_SURROGATE_LEAD(c)) {
+                    if((src+1)!=limit && U16_IS_TRAIL(c2=src[1])) {
+                        c=U16_GET_SUPPLEMENTARY(c, c2);
+                    }
+                } else /* trail surrogate */ {
+                    if(prevSrc<src && U16_IS_LEAD(c2=*(src-1))) {
+                        --src;
+                        c=U16_GET_SUPPLEMENTARY(c2, c);
+                    }
+                }
+                if(isMostDecompYesAndZeroCC(norm16=getNorm16(c))) {
+                    src+=U16_LENGTH(c);
+                } else {
+                    break;
+                }
+            }
+        }
+        // copy these code units all at once
+        if(src!=prevSrc) {
+            if(buffer!=NULL) {
+                if(!buffer->appendZeroCC(prevSrc, src, errorCode)) {
+                    break;
+                }
+            } else {
+                prevCC=0;
+                prevBoundary=src;
+            }
+        }
+        if(src==limit) {
+            break;
+        }
+
+        // Check one above-minimum, relevant code point.
+        src+=U16_LENGTH(c);
+        if(buffer!=NULL) {
+            if(!decompose(c, norm16, *buffer, errorCode)) {
+                break;
+            }
+        } else {
+            if(isDecompYes(norm16)) {
+                uint8_t cc=getCCFromYesOrMaybe(norm16);
+                if(prevCC<=cc || cc==0) {
+                    prevCC=cc;
+                    if(cc<=1) {
+                        prevBoundary=src;
+                    }
+                    continue;
+                }
+            }
+            return prevBoundary;  // "no" or cc out of order
+        }
+    }
+    return src;
+}
+
+// Decompose a short piece of text which is likely to contain characters that
+// fail the quick check loop and/or where the quick check loop's overhead
+// is unlikely to be amortized.
+// Called by the compose() and makeFCD() implementations.
+UBool Normalizer2Impl::decomposeShort(const UChar *src, const UChar *limit,
+                                      ReorderingBuffer &buffer,
+                                      UErrorCode &errorCode) const {
+    while(src<limit) {
+        UChar32 c;
+        uint16_t norm16;
+        UTRIE2_U16_NEXT16(normTrie, src, limit, c, norm16);
+        if(!decompose(c, norm16, buffer, errorCode)) {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+UBool Normalizer2Impl::decompose(UChar32 c, uint16_t norm16,
+                                 ReorderingBuffer &buffer,
+                                 UErrorCode &errorCode) const {
+    // Only loops for 1:1 algorithmic mappings.
+    for(;;) {
+        // get the decomposition and the lead and trail cc's
+        if(isDecompYes(norm16)) {
+            // c does not decompose
+            return buffer.append(c, getCCFromYesOrMaybe(norm16), errorCode);
+        } else if(isHangul(norm16)) {
+            // Hangul syllable: decompose algorithmically
+            UChar jamos[3];
+            return buffer.appendZeroCC(jamos, jamos+Hangul::decompose(c, jamos), errorCode);
+        } else if(isDecompNoAlgorithmic(norm16)) {
+            c=mapAlgorithmic(c, norm16);
+            norm16=getNorm16(c);
+        } else {
+            // c decomposes, get everything from the variable-length extra data
+            const uint16_t *mapping=getMapping(norm16);
+            uint16_t firstUnit=*mapping++;
+            int32_t length=firstUnit&MAPPING_LENGTH_MASK;
+            uint8_t leadCC, trailCC;
+            trailCC=(uint8_t)(firstUnit>>8);
+            if(firstUnit&MAPPING_HAS_CCC_LCCC_WORD) {
+                leadCC=(uint8_t)(*mapping++>>8);
+            } else {
+                leadCC=0;
+            }
+            return buffer.append((const UChar *)mapping, length, leadCC, trailCC, errorCode);
+        }
+    }
+}
+
+const UChar *
+Normalizer2Impl::getDecomposition(UChar32 c, UChar buffer[4], int32_t &length) const {
+    const UChar *decomp=NULL;
+    uint16_t norm16;
+    for(;;) {
+        if(c<minDecompNoCP || isDecompYes(norm16=getNorm16(c))) {
+            // c does not decompose
+            return decomp;
+        } else if(isHangul(norm16)) {
+            // Hangul syllable: decompose algorithmically
+            length=Hangul::decompose(c, buffer);
+            return buffer;
+        } else if(isDecompNoAlgorithmic(norm16)) {
+            c=mapAlgorithmic(c, norm16);
+            decomp=buffer;
+            length=0;
+            U16_APPEND_UNSAFE(buffer, length, c);
+        } else {
+            // c decomposes, get everything from the variable-length extra data
+            const uint16_t *mapping=getMapping(norm16);
+            uint16_t firstUnit=*mapping++;
+            length=firstUnit&MAPPING_LENGTH_MASK;
+            if(firstUnit&MAPPING_HAS_CCC_LCCC_WORD) {
+                ++mapping;
+            }
+            return (const UChar *)mapping;
+        }
+    }
+}
+
+void Normalizer2Impl::decomposeAndAppend(const UChar *src, const UChar *limit,
+                                         UBool doDecompose,
+                                         ReorderingBuffer &buffer,
+                                         UErrorCode &errorCode) const {
+    if(doDecompose) {
+        decompose(src, limit, &buffer, errorCode);
+        return;
+    }
+    // Just merge the strings at the boundary.
+    ForwardUTrie2StringIterator iter(normTrie, src, limit);
+    uint8_t firstCC, prevCC, cc;
+    firstCC=prevCC=cc=getCC(iter.next16());
+    while(cc!=0) {
+        prevCC=cc;
+        cc=getCC(iter.next16());
+    };
+    buffer.append(src, (int32_t)(iter.codePointStart-src), firstCC, prevCC, errorCode) &&
+        buffer.appendZeroCC(iter.codePointStart, limit, errorCode);
+}
+
+// Note: hasDecompBoundary() could be implemented as aliases to
+// hasFCDBoundaryBefore() and hasFCDBoundaryAfter()
+// at the cost of building the FCD trie for a decomposition normalizer.
+UBool Normalizer2Impl::hasDecompBoundary(UChar32 c, UBool before) const {
+    for(;;) {
+        if(c<minDecompNoCP) {
+            return TRUE;
+        }
+        uint16_t norm16=getNorm16(c);
+        if(isHangul(norm16) || isDecompYesAndZeroCC(norm16)) {
+            return TRUE;
+        } else if(norm16>MIN_NORMAL_MAYBE_YES) {
+            return FALSE;  // ccc!=0
+        } else if(isDecompNoAlgorithmic(norm16)) {
+            c=mapAlgorithmic(c, norm16);
+        } else {
+            // c decomposes, get everything from the variable-length extra data
+            const uint16_t *mapping=getMapping(norm16);
+            uint16_t firstUnit=*mapping++;
+            if((firstUnit&MAPPING_LENGTH_MASK)==0) {
+                return FALSE;
+            }
+            if(!before) {
+                // decomp after-boundary: same as hasFCDBoundaryAfter(),
+                // fcd16<=1 || trailCC==0
+                if(firstUnit>0x1ff) {
+                    return FALSE;  // trailCC>1
+                }
+                if(firstUnit<=0xff) {
+                    return TRUE;  // trailCC==0
+                }
+                // if(trailCC==1) test leadCC==0, same as checking for before-boundary
+            }
+            // TRUE if leadCC==0 (hasFCDBoundaryBefore())
+            return (firstUnit&MAPPING_HAS_CCC_LCCC_WORD)==0 || (*mapping&0xff00)==0;
+        }
+    }
+}
+
+/*
+ * Finds the recomposition result for
+ * a forward-combining "lead" character,
+ * specified with a pointer to its compositions list,
+ * and a backward-combining "trail" character.
+ *
+ * If the lead and trail characters combine, then this function returns
+ * the following "compositeAndFwd" value:
+ * Bits 21..1  composite character
+ * Bit      0  set if the composite is a forward-combining starter
+ * otherwise it returns -1.
+ *
+ * The compositions list has (trail, compositeAndFwd) pair entries,
+ * encoded as either pairs or triples of 16-bit units.
+ * The last entry has the high bit of its first unit set.
+ *
+ * The list is sorted by ascending trail characters (there are no duplicates).
+ * A linear search is used.
+ *
+ * See normalizer2impl.h for a more detailed description
+ * of the compositions list format.
+ */
+int32_t Normalizer2Impl::combine(const uint16_t *list, UChar32 trail) {
+    uint16_t key1, firstUnit;
+    if(trail<COMP_1_TRAIL_LIMIT) {
+        // trail character is 0..33FF
+        // result entry may have 2 or 3 units
+        key1=(uint16_t)(trail<<1);
+        while(key1>(firstUnit=*list)) {
+            list+=2+(firstUnit&COMP_1_TRIPLE);
+        }
+        if(key1==(firstUnit&COMP_1_TRAIL_MASK)) {
+            if(firstUnit&COMP_1_TRIPLE) {
+                return ((int32_t)list[1]<<16)|list[2];
+            } else {
+                return list[1];
+            }
+        }
+    } else {
+        // trail character is 3400..10FFFF
+        // result entry has 3 units
+        key1=(uint16_t)(COMP_1_TRAIL_LIMIT+
+                        ((trail>>COMP_1_TRAIL_SHIFT))&
+                         ~COMP_1_TRIPLE);
+        uint16_t key2=(uint16_t)(trail<<COMP_2_TRAIL_SHIFT);
+        uint16_t secondUnit;
+        for(;;) {
+            if(key1>(firstUnit=*list)) {
+                list+=2+(firstUnit&COMP_1_TRIPLE);
+            } else if(key1==(firstUnit&COMP_1_TRAIL_MASK)) {
+                if(key2>(secondUnit=list[1])) {
+                    if(firstUnit&COMP_1_LAST_TUPLE) {
+                        break;
+                    } else {
+                        list+=3;
+                    }
+                } else if(key2==(secondUnit&COMP_2_TRAIL_MASK)) {
+                    return ((int32_t)(secondUnit&~COMP_2_TRAIL_MASK)<<16)|list[2];
+                } else {
+                    break;
+                }
+            } else {
+                break;
+            }
+        }
+    }
+    return -1;
+}
+
+/*
+ * Recomposes the buffer text starting at recomposeStartIndex
+ * (which is in NFD - decomposed and canonically ordered),
+ * and truncates the buffer contents.
+ *
+ * Note that recomposition never lengthens the text:
+ * Any character consists of either one or two code units;
+ * a composition may contain at most one more code unit than the original starter,
+ * while the combining mark that is removed has at least one code unit.
+ */
+void Normalizer2Impl::recompose(ReorderingBuffer &buffer, int32_t recomposeStartIndex,
+                                UBool onlyContiguous) const {
+    UChar *p=buffer.getStart()+recomposeStartIndex;
+    UChar *limit=buffer.getLimit();
+    if(p==limit) {
+        return;
+    }
+
+    UChar *starter, *pRemove, *q, *r;
+    const uint16_t *compositionsList;
+    UChar32 c, compositeAndFwd;
+    uint16_t norm16;
+    uint8_t cc, prevCC;
+    UBool starterIsSupplementary;
+
+    // Some of the following variables are not used until we have a forward-combining starter
+    // and are only initialized now to avoid compiler warnings.
+    compositionsList=NULL;  // used as indicator for whether we have a forward-combining starter
+    starter=NULL;
+    starterIsSupplementary=FALSE;
+    prevCC=0;
+
+    for(;;) {
+        UTRIE2_U16_NEXT16(normTrie, p, limit, c, norm16);
+        cc=getCCFromYesOrMaybe(norm16);
+        if( // this character combines backward and
+            isMaybe(norm16) &&
+            // we have seen a starter that combines forward and
+            compositionsList!=NULL &&
+            // the backward-combining character is not blocked
+            (prevCC<cc || prevCC==0)
+        ) {
+            if(isJamoVT(norm16)) {
+                // c is a Jamo V/T, see if we can compose it with the previous character.
+                if(c<Hangul::JAMO_T_BASE) {
+                    // c is a Jamo Vowel, compose with previous Jamo L and following Jamo T.
+                    UChar prev=(UChar)(*starter-Hangul::JAMO_L_BASE);
+                    if(prev<Hangul::JAMO_L_COUNT) {
+                        pRemove=p-1;
+                        UChar syllable=(UChar)
+                            (Hangul::HANGUL_BASE+
+                             (prev*Hangul::JAMO_V_COUNT+(c-Hangul::JAMO_V_BASE))*
+                             Hangul::JAMO_T_COUNT);
+                        UChar t;
+                        if(p!=limit && (t=(UChar)(*p-Hangul::JAMO_T_BASE))<Hangul::JAMO_T_COUNT) {
+                            ++p;
+                            syllable+=t;  // The next character was a Jamo T.
+                        }
+                        *starter=syllable;
+                        // remove the Jamo V/T
+                        q=pRemove;
+                        r=p;
+                        while(r<limit) {
+                            *q++=*r++;
+                        }
+                        limit=q;
+                        p=pRemove;
+                    }
+                }
+                /*
+                 * No "else" for Jamo T:
+                 * Since the input is in NFD, there are no Hangul LV syllables that
+                 * a Jamo T could combine with.
+                 * All Jamo Ts are combined above when handling Jamo Vs.
+                 */
+                if(p==limit) {
+                    break;
+                }
+                compositionsList=NULL;
+                continue;
+            } else if((compositeAndFwd=combine(compositionsList, c))>=0) {
+                // The starter and the combining mark (c) do combine.
+                UChar32 composite=compositeAndFwd>>1;
+
+                // Replace the starter with the composite, remove the combining mark.
+                pRemove=p-U16_LENGTH(c);  // pRemove & p: start & limit of the combining mark
+                if(starterIsSupplementary) {
+                    if(U_IS_SUPPLEMENTARY(composite)) {
+                        // both are supplementary
+                        starter[0]=U16_LEAD(composite);
+                        starter[1]=U16_TRAIL(composite);
+                    } else {
+                        *starter=(UChar)composite;
+                        // The composite is shorter than the starter,
+                        // move the intermediate characters forward one.
+                        starterIsSupplementary=FALSE;
+                        q=starter+1;
+                        r=q+1;
+                        while(r<pRemove) {
+                            *q++=*r++;
+                        }
+                        --pRemove;
+                    }
+                } else if(U_IS_SUPPLEMENTARY(composite)) {
+                    // The composite is longer than the starter,
+                    // move the intermediate characters back one.
+                    starterIsSupplementary=TRUE;
+                    ++starter;  // temporarily increment for the loop boundary
+                    q=pRemove;
+                    r=++pRemove;
+                    while(starter<q) {
+                        *--r=*--q;
+                    }
+                    *starter=U16_TRAIL(composite);
+                    *--starter=U16_LEAD(composite);  // undo the temporary increment
+                } else {
+                    // both are on the BMP
+                    *starter=(UChar)composite;
+                }
+
+                /* remove the combining mark by moving the following text over it */
+                if(pRemove<p) {
+                    q=pRemove;
+                    r=p;
+                    while(r<limit) {
+                        *q++=*r++;
+                    }
+                    limit=q;
+                    p=pRemove;
+                }
+                // Keep prevCC because we removed the combining mark.
+
+                if(p==limit) {
+                    break;
+                }
+                // Is the composite a starter that combines forward?
+                if(compositeAndFwd&1) {
+                    compositionsList=
+                        getCompositionsListForComposite(getNorm16(composite));
+                } else {
+                    compositionsList=NULL;
+                }
+
+                // We combined; continue with looking for compositions.
+                continue;
+            }
+        }
+
+        // no combination this time
+        prevCC=cc;
+        if(p==limit) {
+            break;
+        }
+
+        // If c did not combine, then check if it is a starter.
+        if(cc==0) {
+            // Found a new starter.
+            if((compositionsList=getCompositionsListForDecompYes(norm16))!=NULL) {
+                // It may combine with something, prepare for it.
+                if(U_IS_BMP(c)) {
+                    starterIsSupplementary=FALSE;
+                    starter=p-1;
+                } else {
+                    starterIsSupplementary=TRUE;
+                    starter=p-2;
+                }
+            }
+        } else if(onlyContiguous) {
+            // FCC: no discontiguous compositions; any intervening character blocks.
+            compositionsList=NULL;
+        }
+    }
+    buffer.setReorderingLimit(limit);
+}
+
+// Very similar to composeQuickCheck(): Make the same changes in both places if relevant.
+// doCompose: normalize
+// !doCompose: isNormalized (buffer must be empty and initialized)
+UBool
+Normalizer2Impl::compose(const UChar *src, const UChar *limit,
+                         UBool onlyContiguous,
+                         UBool doCompose,
+                         ReorderingBuffer &buffer,
+                         UErrorCode &errorCode) const {
+    UChar32 minNoMaybeCP=minCompNoMaybeCP;
+    if(limit==NULL) {
+        src=copyLowPrefixFromNulTerminated(src, minNoMaybeCP,
+                                           doCompose ? &buffer : NULL,
+                                           errorCode);
+        if(U_FAILURE(errorCode)) {
+            return FALSE;
+        }
+        limit=u_strchr(src, 0);
+    }
+
+    /*
+     * prevBoundary points to the last character before the current one
+     * that has a composition boundary before it with ccc==0 and quick check "yes".
+     * Keeping track of prevBoundary saves us looking for a composition boundary
+     * when we find a "no" or "maybe".
+     *
+     * When we back out from prevSrc back to prevBoundary,
+     * then we also remove those same characters (which had been simply copied
+     * or canonically-order-inserted) from the ReorderingBuffer.
+     * Therefore, at all times, the [prevBoundary..prevSrc[ source units
+     * must correspond 1:1 to destination units at the end of the destination buffer.
+     */
+    const UChar *prevBoundary=src;
+    const UChar *prevSrc;
+    UChar32 c=0;
+    uint16_t norm16=0;
+
+    // only for isNormalized
+    uint8_t prevCC=0;
+
+    for(;;) {
+        // count code units below the minimum or with irrelevant data for the quick check
+        for(prevSrc=src; src!=limit;) {
+            if( (c=*src)<minNoMaybeCP ||
+                isCompYesAndZeroCC(norm16=UTRIE2_GET16_FROM_U16_SINGLE_LEAD(normTrie, c))
+            ) {
+                ++src;
+            } else if(!U16_IS_SURROGATE(c)) {
+                break;
+            } else {
+                UChar c2;
+                if(U16_IS_SURROGATE_LEAD(c)) {
+                    if((src+1)!=limit && U16_IS_TRAIL(c2=src[1])) {
+                        c=U16_GET_SUPPLEMENTARY(c, c2);
+                    }
+                } else /* trail surrogate */ {
+                    if(prevSrc<src && U16_IS_LEAD(c2=*(src-1))) {
+                        --src;
+                        c=U16_GET_SUPPLEMENTARY(c2, c);
+                    }
+                }
+                if(isCompYesAndZeroCC(norm16=getNorm16(c))) {
+                    src+=U16_LENGTH(c);
+                } else {
+                    break;
+                }
+            }
+        }
+        // copy these code units all at once
+        if(src!=prevSrc) {
+            if(doCompose) {
+                if(!buffer.appendZeroCC(prevSrc, src, errorCode)) {
+                    break;
+                }
+            } else {
+                prevCC=0;
+            }
+            if(src==limit) {
+                break;
+            }
+            // Set prevBoundary to the last character in the quick check loop.
+            prevBoundary=src-1;
+            if( U16_IS_TRAIL(*prevBoundary) && prevSrc<prevBoundary &&
+                U16_IS_LEAD(*(prevBoundary-1))
+            ) {
+                --prevBoundary;
+            }
+            // The start of the current character (c).
+            prevSrc=src;
+        } else if(src==limit) {
+            break;
+        }
+
+        src+=U16_LENGTH(c);
+        /*
+         * isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo.
+         * c is either a "noNo" (has a mapping) or a "maybeYes" (combines backward)
+         * or has ccc!=0.
+         * Check for Jamo V/T, then for regular characters.
+         * c is not a Hangul syllable or Jamo L because those have "yes" properties.
+         */
+        if(isJamoVT(norm16) && prevBoundary!=prevSrc) {
+            UChar prev=*(prevSrc-1);
+            UBool needToDecompose=FALSE;
+            if(c<Hangul::JAMO_T_BASE) {
+                // c is a Jamo Vowel, compose with previous Jamo L and following Jamo T.
+                prev=(UChar)(prev-Hangul::JAMO_L_BASE);
+                if(prev<Hangul::JAMO_L_COUNT) {
+                    if(!doCompose) {
+                        return FALSE;
+                    }
+                    UChar syllable=(UChar)
+                        (Hangul::HANGUL_BASE+
+                         (prev*Hangul::JAMO_V_COUNT+(c-Hangul::JAMO_V_BASE))*
+                         Hangul::JAMO_T_COUNT);
+                    UChar t;
+                    if(src!=limit && (t=(UChar)(*src-Hangul::JAMO_T_BASE))<Hangul::JAMO_T_COUNT) {
+                        ++src;
+                        syllable+=t;  // The next character was a Jamo T.
+                        prevBoundary=src;
+                        buffer.setLastChar(syllable);
+                        continue;
+                    }
+                    // If we see L+V+x where x!=T then we drop to the slow path,
+                    // decompose and recompose.
+                    // This is to deal with NFKC finding normal L and V but a
+                    // compatibility variant of a T. We need to either fully compose that
+                    // combination here (which would complicate the code and may not work
+                    // with strange custom data) or use the slow path -- or else our replacing
+                    // two input characters (L+V) with one output character (LV syllable)
+                    // would violate the invariant that [prevBoundary..prevSrc[ has the same
+                    // length as what we appended to the buffer since prevBoundary.
+                    needToDecompose=TRUE;
+                }
+            } else if(Hangul::isHangulWithoutJamoT(prev)) {
+                // c is a Jamo Trailing consonant,
+                // compose with previous Hangul LV that does not contain a Jamo T.
+                if(!doCompose) {
+                    return FALSE;
+                }
+                buffer.setLastChar((UChar)(prev+c-Hangul::JAMO_T_BASE));
+                prevBoundary=src;
+                continue;
+            }
+            if(!needToDecompose) {
+                // The Jamo V/T did not compose into a Hangul syllable.
+                if(doCompose) {
+                    if(!buffer.appendBMP((UChar)c, 0, errorCode)) {
+                        break;
+                    }
+                } else {
+                    prevCC=0;
+                }
+                continue;
+            }
+        }
+        /*
+         * Source buffer pointers:
+         *
+         *  all done      quick check   current char  not yet
+         *                "yes" but     (c)           processed
+         *                may combine
+         *                forward
+         * [-------------[-------------[-------------[-------------[
+         * |             |             |             |             |
+         * orig. src     prevBoundary  prevSrc       src           limit
+         *
+         *
+         * Destination buffer pointers inside the ReorderingBuffer:
+         *
+         *  all done      might take    not filled yet
+         *                characters for
+         *                reordering
+         * [-------------[-------------[-------------[
+         * |             |             |             |
+         * start         reorderStart  limit         |
+         *                             +remainingCap.+
+         */
+        if(norm16>=MIN_YES_YES_WITH_CC) {
+            uint8_t cc=(uint8_t)norm16;  // cc!=0
+            if( onlyContiguous &&  // FCC
+                (doCompose ? buffer.getLastCC() : prevCC)==0 &&
+                prevBoundary<prevSrc &&
+                // buffer.getLastCC()==0 && prevBoundary<prevSrc tell us that
+                // [prevBoundary..prevSrc[ (which is exactly one character under these conditions)
+                // passed the quick check "yes && ccc==0" test.
+                // Check whether the last character was a "yesYes" or a "yesNo".
+                // If a "yesNo", then we get its trailing ccc from its
+                // mapping and check for canonical order.
+                // All other cases are ok.
+                getTrailCCFromCompYesAndZeroCC(prevBoundary, prevSrc)>cc
+            ) {
+                // Fails FCD test, need to decompose and contiguously recompose.
+                if(!doCompose) {
+                    return FALSE;
+                }
+            } else if(doCompose) {
+                if(!buffer.append(c, cc, errorCode)) {
+                    break;
+                }
+                continue;
+            } else if(prevCC<=cc) {
+                prevCC=cc;
+                continue;
+            } else {
+                return FALSE;
+            }
+        } else if(!doCompose && !isMaybeOrNonZeroCC(norm16)) {
+            return FALSE;
+        }
+
+        /*
+         * Find appropriate boundaries around this character,
+         * decompose the source text from between the boundaries,
+         * and recompose it.
+         *
+         * We may need to remove the last few characters from the ReorderingBuffer
+         * to account for source text that was copied or appended
+         * but needs to take part in the recomposition.
+         */
+
+        /*
+         * Find the last composition boundary in [prevBoundary..src[.
+         * It is either the decomposition of the current character (at prevSrc),
+         * or prevBoundary.
+         */
+        if(hasCompBoundaryBefore(c, norm16)) {
+            prevBoundary=prevSrc;
+        } else if(doCompose) {
+            buffer.removeSuffix((int32_t)(prevSrc-prevBoundary));
+        }
+
+        // Find the next composition boundary in [src..limit[ -
+        // modifies src to point to the next starter.
+        src=(UChar *)findNextCompBoundary(src, limit);
+
+        // Decompose [prevBoundary..src[ into the buffer and then recompose that part of it.
+        int32_t recomposeStartIndex=buffer.length();
+        if(!decomposeShort(prevBoundary, src, buffer, errorCode)) {
+            break;
+        }
+        recompose(buffer, recomposeStartIndex, onlyContiguous);
+        if(!doCompose) {
+            if(!buffer.equals(prevBoundary, src)) {
+                return FALSE;
+            }
+            buffer.remove();
+            prevCC=0;
+        }
+
+        // Move to the next starter. We never need to look back before this point again.
+        prevBoundary=src;
+    }
+    return TRUE;
+}
+
+// Very similar to compose(): Make the same changes in both places if relevant.
+// pQCResult==NULL: spanQuickCheckYes
+// pQCResult!=NULL: quickCheck (*pQCResult must be UNORM_YES)
+const UChar *
+Normalizer2Impl::composeQuickCheck(const UChar *src, const UChar *limit,
+                                   UBool onlyContiguous,
+                                   UNormalizationCheckResult *pQCResult) const {
+    UChar32 minNoMaybeCP=minCompNoMaybeCP;
+    if(limit==NULL) {
+        UErrorCode errorCode=U_ZERO_ERROR;
+        src=copyLowPrefixFromNulTerminated(src, minNoMaybeCP, NULL, errorCode);
+        limit=u_strchr(src, 0);
+    }
+
+    /*
+     * prevBoundary points to the last character before the current one
+     * that has a composition boundary before it with ccc==0 and quick check "yes".
+     */
+    const UChar *prevBoundary=src;
+    const UChar *prevSrc;
+    UChar32 c=0;
+    uint16_t norm16=0;
+    uint8_t prevCC=0;
+
+    for(;;) {
+        // count code units below the minimum or with irrelevant data for the quick check
+        for(prevSrc=src;;) {
+            if(src==limit) {
+                return src;
+            }
+            if( (c=*src)<minNoMaybeCP ||
+                isCompYesAndZeroCC(norm16=UTRIE2_GET16_FROM_U16_SINGLE_LEAD(normTrie, c))
+            ) {
+                ++src;
+            } else if(!U16_IS_SURROGATE(c)) {
+                break;
+            } else {
+                UChar c2;
+                if(U16_IS_SURROGATE_LEAD(c)) {
+                    if((src+1)!=limit && U16_IS_TRAIL(c2=src[1])) {
+                        c=U16_GET_SUPPLEMENTARY(c, c2);
+                    }
+                } else /* trail surrogate */ {
+                    if(prevSrc<src && U16_IS_LEAD(c2=*(src-1))) {
+                        --src;
+                        c=U16_GET_SUPPLEMENTARY(c2, c);
+                    }
+                }
+                if(isCompYesAndZeroCC(norm16=getNorm16(c))) {
+                    src+=U16_LENGTH(c);
+                } else {
+                    break;
+                }
+            }
+        }
+        if(src!=prevSrc) {
+            // Set prevBoundary to the last character in the quick check loop.
+            prevBoundary=src-1;
+            if( U16_IS_TRAIL(*prevBoundary) && prevSrc<prevBoundary &&
+                U16_IS_LEAD(*(prevBoundary-1))
+            ) {
+                --prevBoundary;
+            }
+            prevCC=0;
+            // The start of the current character (c).
+            prevSrc=src;
+        }
+
+        src+=U16_LENGTH(c);
+        /*
+         * isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo.
+         * c is either a "noNo" (has a mapping) or a "maybeYes" (combines backward)
+         * or has ccc!=0.
+         */
+        if(isMaybeOrNonZeroCC(norm16)) {
+            uint8_t cc=getCCFromYesOrMaybe(norm16);
+            if( onlyContiguous &&  // FCC
+                cc!=0 &&
+                prevCC==0 &&
+                prevBoundary<prevSrc &&
+                // prevCC==0 && prevBoundary<prevSrc tell us that
+                // [prevBoundary..prevSrc[ (which is exactly one character under these conditions)
+                // passed the quick check "yes && ccc==0" test.
+                // Check whether the last character was a "yesYes" or a "yesNo".
+                // If a "yesNo", then we get its trailing ccc from its
+                // mapping and check for canonical order.
+                // All other cases are ok.
+                getTrailCCFromCompYesAndZeroCC(prevBoundary, prevSrc)>cc
+            ) {
+                // Fails FCD test.
+            } else if(prevCC<=cc || cc==0) {
+                prevCC=cc;
+                if(norm16<MIN_YES_YES_WITH_CC) {
+                    if(pQCResult!=NULL) {
+                        *pQCResult=UNORM_MAYBE;
+                    } else {
+                        return prevBoundary;
+                    }
+                }
+                continue;
+            }
+        }
+        if(pQCResult!=NULL) {
+            *pQCResult=UNORM_NO;
+        }
+        return prevBoundary;
+    }
+}
+
+void Normalizer2Impl::composeAndAppend(const UChar *src, const UChar *limit,
+                                       UBool doCompose,
+                                       UBool onlyContiguous,
+                                       ReorderingBuffer &buffer,
+                                       UErrorCode &errorCode) const {
+    if(!buffer.isEmpty()) {
+        const UChar *firstStarterInSrc=findNextCompBoundary(src, limit);
+        if(src!=firstStarterInSrc) {
+            const UChar *lastStarterInDest=findPreviousCompBoundary(buffer.getStart(),
+                                                                    buffer.getLimit());
+            UnicodeString middle(lastStarterInDest,
+                                 (int32_t)(buffer.getLimit()-lastStarterInDest));
+            buffer.removeSuffix((int32_t)(buffer.getLimit()-lastStarterInDest));
+            middle.append(src, (int32_t)(firstStarterInSrc-src));
+            const UChar *middleStart=middle.getBuffer();
+            compose(middleStart, middleStart+middle.length(), onlyContiguous,
+                    TRUE, buffer, errorCode);
+            if(U_FAILURE(errorCode)) {
+                return;
+            }
+            src=firstStarterInSrc;
+        }
+    }
+    if(doCompose) {
+        compose(src, limit, onlyContiguous, TRUE, buffer, errorCode);
+    } else {
+        buffer.appendZeroCC(src, limit, errorCode);
+    }
+}
+
+/**
+ * Does c have a composition boundary before it?
+ * True if its decomposition begins with a character that has
+ * ccc=0 && NFC_QC=Yes (isCompYesAndZeroCC()).
+ * As a shortcut, this is true if c itself has ccc=0 && NFC_QC=Yes
+ * (isCompYesAndZeroCC()) so we need not decompose.
+ */
+UBool Normalizer2Impl::hasCompBoundaryBefore(UChar32 c, uint16_t norm16) const {
+    for(;;) {
+        if(isCompYesAndZeroCC(norm16)) {
+            return TRUE;
+        } else if(isMaybeOrNonZeroCC(norm16)) {
+            return FALSE;
+        } else if(isDecompNoAlgorithmic(norm16)) {
+            c=mapAlgorithmic(c, norm16);
+            norm16=getNorm16(c);
+        } else {
+            // c decomposes, get everything from the variable-length extra data
+            const uint16_t *mapping=getMapping(norm16);
+            uint16_t firstUnit=*mapping++;
+            if((firstUnit&MAPPING_LENGTH_MASK)==0) {
+                return FALSE;
+            }
+            if((firstUnit&MAPPING_HAS_CCC_LCCC_WORD) && (*mapping++&0xff00)) {
+                return FALSE;  // non-zero leadCC
+            }
+            int32_t i=0;
+            UChar32 c;
+            U16_NEXT_UNSAFE(mapping, i, c);
+            return isCompYesAndZeroCC(getNorm16(c));
+        }
+    }
+}
+
+UBool Normalizer2Impl::hasCompBoundaryAfter(UChar32 c, UBool onlyContiguous, UBool testInert) const {
+    for(;;) {
+        uint16_t norm16=getNorm16(c);
+        if(isInert(norm16)) {
+            return TRUE;
+        } else if(norm16<=minYesNo) {
+            // Hangul LVT (==minYesNo) has a boundary after it.
+            // Hangul LV and non-inert yesYes characters combine forward.
+            return isHangul(norm16) && !Hangul::isHangulWithoutJamoT((UChar)c);
+        } else if(norm16>= (testInert ? minNoNo : minMaybeYes)) {
+            return FALSE;
+        } else if(isDecompNoAlgorithmic(norm16)) {
+            c=mapAlgorithmic(c, norm16);
+        } else {
+            // c decomposes, get everything from the variable-length extra data.
+            // If testInert, then c must be a yesNo character which has lccc=0,
+            // otherwise it could be a noNo.
+            const uint16_t *mapping=getMapping(norm16);
+            uint16_t firstUnit=*mapping;
+            // TRUE if
+            //      c is not deleted, and
+            //      it and its decomposition do not combine forward, and it has a starter, and
+            //      if FCC then trailCC<=1
+            return
+                (firstUnit&MAPPING_LENGTH_MASK)!=0 &&
+                (firstUnit&(MAPPING_PLUS_COMPOSITION_LIST|MAPPING_NO_COMP_BOUNDARY_AFTER))==0 &&
+                (!onlyContiguous || firstUnit<=0x1ff);
+        }
+    }
+}
+
+const UChar *Normalizer2Impl::findPreviousCompBoundary(const UChar *start, const UChar *p) const {
+    BackwardUTrie2StringIterator iter(normTrie, start, p);
+    uint16_t norm16;
+    do {
+        norm16=iter.previous16();
+    } while(!hasCompBoundaryBefore(iter.codePoint, norm16));
+    // We could also test hasCompBoundaryAfter() and return iter.codePointLimit,
+    // but that's probably not worth the extra cost.
+    return iter.codePointStart;
+}
+
+const UChar *Normalizer2Impl::findNextCompBoundary(const UChar *p, const UChar *limit) const {
+    ForwardUTrie2StringIterator iter(normTrie, p, limit);
+    uint16_t norm16;
+    do {
+        norm16=iter.next16();
+    } while(!hasCompBoundaryBefore(iter.codePoint, norm16));
+    return iter.codePointStart;
+}
+
+class FCDTrieSingleton : public UTrie2Singleton {
+public:
+    FCDTrieSingleton(SimpleSingleton &s, Normalizer2Impl &ni, UErrorCode &ec) :
+        UTrie2Singleton(s), impl(ni), errorCode(ec) {}
+    UTrie2 *getInstance(UErrorCode &errorCode) {
+        return UTrie2Singleton::getInstance(createInstance, this, errorCode);
+    }
+    static void *createInstance(const void *context, UErrorCode &errorCode);
+    UBool rangeHandler(UChar32 start, UChar32 end, uint32_t value) {
+        if(value!=0) {
+            impl.setFCD16FromNorm16(start, end, (uint16_t)value, newFCDTrie, errorCode);
+        }
+        return U_SUCCESS(errorCode);
+    }
+
+    Normalizer2Impl &impl;
+    UTrie2 *newFCDTrie;
+    UErrorCode &errorCode;
+};
+
+U_CDECL_BEGIN
+
+// Set the FCD value for a range of same-norm16 characters.
+static UBool U_CALLCONV
+enumRangeHandler(const void *context, UChar32 start, UChar32 end, uint32_t value) {
+    return ((FCDTrieSingleton *)context)->rangeHandler(start, end, value);
+}
+
+// Collect (OR together) the FCD values for a range of supplementary characters,
+// for their lead surrogate code unit.
+static UBool U_CALLCONV
+enumRangeOrValue(const void *context, UChar32 start, UChar32 end, uint32_t value) {
+    *((uint32_t *)context)|=value;
+    return TRUE;
+}
+
+U_CDECL_END
+
+void *FCDTrieSingleton::createInstance(const void *context, UErrorCode &errorCode) {
+    FCDTrieSingleton *me=(FCDTrieSingleton *)context;
+    me->newFCDTrie=utrie2_open(0, 0, &errorCode);
+    if(U_SUCCESS(errorCode)) {
+        utrie2_enum(me->impl.getNormTrie(), NULL, enumRangeHandler, me);
+        for(UChar lead=0xd800; lead<0xdc00; ++lead) {
+            uint32_t oredValue=utrie2_get32(me->newFCDTrie, lead);
+            utrie2_enumForLeadSurrogate(me->newFCDTrie, lead, NULL, enumRangeOrValue, &oredValue);
+            if(oredValue!=0) {
+                // Set a "bad" value for makeFCD() to break the quick check loop
+                // and look up the value for the supplementary code point.
+                // If there is any lccc, then set the worst-case lccc of 1.
+                // The ORed-together value's tccc is already the worst case.
+                if(oredValue>0xff) {
+                    oredValue=0x100|(oredValue&0xff);
+                }
+                utrie2_set32ForLeadSurrogateCodeUnit(me->newFCDTrie, lead, oredValue, &errorCode);
+            }
+        }
+        utrie2_freeze(me->newFCDTrie, UTRIE2_16_VALUE_BITS, &errorCode);
+        if(U_SUCCESS(errorCode)) {
+            return me->newFCDTrie;
+        }
+    }
+    utrie2_close(me->newFCDTrie);
+    return NULL;
+}
+
+void Normalizer2Impl::setFCD16FromNorm16(UChar32 start, UChar32 end, uint16_t norm16,
+                                         UTrie2 *newFCDTrie, UErrorCode &errorCode) const {
+    // Only loops for 1:1 algorithmic mappings.
+    for(;;) {
+        if(norm16>=MIN_NORMAL_MAYBE_YES) {
+            norm16&=0xff;
+            norm16|=norm16<<8;
+        } else if(norm16<=minYesNo || minMaybeYes<=norm16) {
+            // no decomposition or Hangul syllable, all zeros
+            break;
+        } else if(limitNoNo<=norm16) {
+            int32_t delta=norm16-(minMaybeYes-MAX_DELTA-1);
+            if(start==end) {
+                start+=delta;
+                norm16=getNorm16(start);
+            } else {
+                // the same delta leads from different original characters to different mappings
+                do {
+                    UChar32 c=start+delta;
+                    setFCD16FromNorm16(c, c, getNorm16(c), newFCDTrie, errorCode);
+                } while(++start<=end);
+                break;
+            }
+        } else {
+            // c decomposes, get everything from the variable-length extra data
+            const uint16_t *mapping=getMapping(norm16);
+            uint16_t firstUnit=*mapping;
+            if((firstUnit&MAPPING_LENGTH_MASK)==0) {
+                // A character that is deleted (maps to an empty string) must
+                // get the worst-case lccc and tccc values because arbitrary
+                // characters on both sides will become adjacent.
+                norm16=0x1ff;
+            } else {
+                if(firstUnit&MAPPING_HAS_CCC_LCCC_WORD) {
+                    norm16=mapping[1]&0xff00;  // lccc
+                } else {
+                    norm16=0;
+                }
+                norm16|=firstUnit>>8;  // tccc
+            }
+        }
+        utrie2_setRange32(newFCDTrie, start, end, norm16, TRUE, &errorCode);
+        break;
+    }
+}
+
+const UTrie2 *Normalizer2Impl::getFCDTrie(UErrorCode &errorCode) const {
+    // Logically const: Synchronized instantiation.
+    Normalizer2Impl *me=const_cast<Normalizer2Impl *>(this);
+    return FCDTrieSingleton(me->fcdTrieSingleton, *me, errorCode).getInstance(errorCode);
+}
+
+// Dual functionality:
+// buffer!=NULL: normalize
+// buffer==NULL: isNormalized/quickCheck/spanQuickCheckYes
+const UChar *
+Normalizer2Impl::makeFCD(const UChar *src, const UChar *limit,
+                         ReorderingBuffer *buffer,
+                         UErrorCode &errorCode) const {
+    if(limit==NULL) {
+        src=copyLowPrefixFromNulTerminated(src, MIN_CCC_LCCC_CP, buffer, errorCode);
+        if(U_FAILURE(errorCode)) {
+            return src;
+        }
+        limit=u_strchr(src, 0);
+    }
+
+    // Note: In this function we use buffer->appendZeroCC() because we track
+    // the lead and trail combining classes here, rather than leaving it to
+    // the ReorderingBuffer.
+    // The exception is the call to decomposeShort() which uses the buffer
+    // in the normal way.
+
+    const UTrie2 *trie=fcdTrie();
+
+    // Tracks the last FCD-safe boundary, before lccc=0 or after properly-ordered tccc<=1.
+    // Similar to the prevBoundary in the compose() implementation.
+    const UChar *prevBoundary=src;
+    const UChar *prevSrc;
+    UChar32 c=0;
+    int32_t prevFCD16=0;
+    uint16_t fcd16=0;
+
+    for(;;) {
+        // count code units with lccc==0
+        for(prevSrc=src; src!=limit;) {
+            if((c=*src)<MIN_CCC_LCCC_CP) {
+                prevFCD16=~c;
+                ++src;
+            } else if((fcd16=UTRIE2_GET16_FROM_U16_SINGLE_LEAD(trie, c))<=0xff) {
+                prevFCD16=fcd16;
+                ++src;
+            } else if(!U16_IS_SURROGATE(c)) {
+                break;
+            } else {
+                UChar c2;
+                if(U16_IS_SURROGATE_LEAD(c)) {
+                    if((src+1)!=limit && U16_IS_TRAIL(c2=src[1])) {
+                        c=U16_GET_SUPPLEMENTARY(c, c2);
+                    }
+                } else /* trail surrogate */ {
+                    if(prevSrc<src && U16_IS_LEAD(c2=*(src-1))) {
+                        --src;
+                        c=U16_GET_SUPPLEMENTARY(c2, c);
+                    }
+                }
+                if((fcd16=getFCD16(c))<=0xff) {
+                    prevFCD16=fcd16;
+                    src+=U16_LENGTH(c);
+                } else {
+                    break;
+                }
+            }
+        }
+        // copy these code units all at once
+        if(src!=prevSrc) {
+            if(buffer!=NULL && !buffer->appendZeroCC(prevSrc, src, errorCode)) {
+                break;
+            }
+            if(src==limit) {
+                break;
+            }
+            prevBoundary=src;
+            // We know that the previous character's lccc==0.
+            if(prevFCD16<0) {
+                // Fetching the fcd16 value was deferred for this below-U+0300 code point.
+                prevFCD16=getFCD16FromSingleLead((UChar)~prevFCD16);
+                if(prevFCD16>1) {
+                    --prevBoundary;
+                }
+            } else {
+                const UChar *p=src-1;
+                if(U16_IS_TRAIL(*p) && prevSrc<p && U16_IS_LEAD(*(p-1))) {
+                    --p;
+                    // Need to fetch the previous character's FCD value because
+                    // prevFCD16 was just for the trail surrogate code point.
+                    prevFCD16=getFCD16FromSurrogatePair(p[0], p[1]);
+                    // Still known to have lccc==0 because its lead surrogate unit had lccc==0.
+                }
+                if(prevFCD16>1) {
+                    prevBoundary=p;
+                }
+            }
+            // The start of the current character (c).
+            prevSrc=src;
+        } else if(src==limit) {
+            break;
+        }
+
+        src+=U16_LENGTH(c);
+        // The current character (c) at [prevSrc..src[ has a non-zero lead combining class.
+        // Check for proper order, and decompose locally if necessary.
+        if((prevFCD16&0xff)<=(fcd16>>8)) {
+            // proper order: prev tccc <= current lccc
+            if((fcd16&0xff)<=1) {
+                prevBoundary=src;
+            }
+            if(buffer!=NULL && !buffer->appendZeroCC(c, errorCode)) {
+                break;
+            }
+            prevFCD16=fcd16;
+            continue;
+        } else if(buffer==NULL) {
+            return prevBoundary;  // quick check "no"
+        } else {
+            /*
+             * Back out the part of the source that we copied or appended
+             * already but is now going to be decomposed.
+             * prevSrc is set to after what was copied/appended.
+             */
+            buffer->removeSuffix((int32_t)(prevSrc-prevBoundary));
+            /*
+             * Find the part of the source that needs to be decomposed,
+             * up to the next safe boundary.
+             */
+            src=findNextFCDBoundary(src, limit);
+            /*
+             * The source text does not fulfill the conditions for FCD.
+             * Decompose and reorder a limited piece of the text.
+             */
+            if(!decomposeShort(prevBoundary, src, *buffer, errorCode)) {
+                break;
+            }
+            prevBoundary=src;
+            prevFCD16=0;
+        }
+    }
+    return src;
+}
+
+void Normalizer2Impl::makeFCDAndAppend(const UChar *src, const UChar *limit,
+                                       UBool doMakeFCD,
+                                       ReorderingBuffer &buffer,
+                                       UErrorCode &errorCode) const {
+    if(!buffer.isEmpty()) {
+        const UChar *firstBoundaryInSrc=findNextFCDBoundary(src, limit);
+        if(src!=firstBoundaryInSrc) {
+            const UChar *lastBoundaryInDest=findPreviousFCDBoundary(buffer.getStart(),
+                                                                    buffer.getLimit());
+            UnicodeString middle(lastBoundaryInDest,
+                                 (int32_t)(buffer.getLimit()-lastBoundaryInDest));
+            buffer.removeSuffix((int32_t)(buffer.getLimit()-lastBoundaryInDest));
+            middle.append(src, (int32_t)(firstBoundaryInSrc-src));
+            const UChar *middleStart=middle.getBuffer();
+            makeFCD(middleStart, middleStart+middle.length(), &buffer, errorCode);
+            if(U_FAILURE(errorCode)) {
+                return;
+            }
+            src=firstBoundaryInSrc;
+        }
+    }
+    if(doMakeFCD) {
+        makeFCD(src, limit, &buffer, errorCode);
+    } else {
+        buffer.appendZeroCC(src, limit, errorCode);
+    }
+}
+
+const UChar *Normalizer2Impl::findPreviousFCDBoundary(const UChar *start, const UChar *p) const {
+    BackwardUTrie2StringIterator iter(fcdTrie(), start, p);
+    uint16_t fcd16;
+    do {
+        fcd16=iter.previous16();
+    } while(fcd16>0xff);
+    return iter.codePointStart;
+}
+
+const UChar *Normalizer2Impl::findNextFCDBoundary(const UChar *p, const UChar *limit) const {
+    ForwardUTrie2StringIterator iter(fcdTrie(), p, limit);
+    uint16_t fcd16;
+    do {
+        fcd16=iter.next16();
+    } while(fcd16>0xff);
+    return iter.codePointStart;
+}
+
+U_NAMESPACE_END
+
+// Normalizer2 data swapping ----------------------------------------------- ***
+
+U_NAMESPACE_USE
+
+U_CAPI int32_t U_EXPORT2
+unorm2_swap(const UDataSwapper *ds,
+            const void *inData, int32_t length, void *outData,
+            UErrorCode *pErrorCode) {
+    const UDataInfo *pInfo;
+    int32_t headerSize;
+
+    const uint8_t *inBytes;
+    uint8_t *outBytes;
+
+    const int32_t *inIndexes;
+    int32_t indexes[Normalizer2Impl::IX_MIN_MAYBE_YES+1];
+
+    int32_t i, offset, nextOffset, size;
+
+    /* udata_swapDataHeader checks the arguments */
+    headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    /* check data format and format version */
+    pInfo=(const UDataInfo *)((const char *)inData+4);
+    if(!(
+        pInfo->dataFormat[0]==0x4e &&   /* dataFormat="Nrm2" */
+        pInfo->dataFormat[1]==0x72 &&
+        pInfo->dataFormat[2]==0x6d &&
+        pInfo->dataFormat[3]==0x32 &&
+        pInfo->formatVersion[0]==1
+    )) {
+        udata_printError(ds, "unorm2_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as Normalizer2 data\n",
+                         pInfo->dataFormat[0], pInfo->dataFormat[1],
+                         pInfo->dataFormat[2], pInfo->dataFormat[3],
+                         pInfo->formatVersion[0]);
+        *pErrorCode=U_UNSUPPORTED_ERROR;
+        return 0;
+    }
+
+    inBytes=(const uint8_t *)inData+headerSize;
+    outBytes=(uint8_t *)outData+headerSize;
+
+    inIndexes=(const int32_t *)inBytes;
+
+    if(length>=0) {
+        length-=headerSize;
+        if(length<sizeof(indexes)) {
+            udata_printError(ds, "unorm2_swap(): too few bytes (%d after header) for Normalizer2 data\n",
+                             length);
+            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+            return 0;
+        }
+    }
+
+    /* read the first few indexes */
+    for(i=0; i<=Normalizer2Impl::IX_MIN_MAYBE_YES; ++i) {
+        indexes[i]=udata_readInt32(ds, inIndexes[i]);
+    }
+
+    /* get the total length of the data */
+    size=indexes[Normalizer2Impl::IX_TOTAL_SIZE];
+
+    if(length>=0) {
+        if(length<size) {
+            udata_printError(ds, "unorm2_swap(): too few bytes (%d after header) for all of Normalizer2 data\n",
+                             length);
+            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+            return 0;
+        }
+
+        /* copy the data for inaccessible bytes */
+        if(inBytes!=outBytes) {
+            uprv_memcpy(outBytes, inBytes, size);
+        }
+
+        offset=0;
+
+        /* swap the int32_t indexes[] */
+        nextOffset=indexes[Normalizer2Impl::IX_NORM_TRIE_OFFSET];
+        ds->swapArray32(ds, inBytes, nextOffset-offset, outBytes, pErrorCode);
+        offset=nextOffset;
+
+        /* swap the UTrie2 */
+        nextOffset=indexes[Normalizer2Impl::IX_EXTRA_DATA_OFFSET];
+        utrie2_swap(ds, inBytes+offset, nextOffset-offset, outBytes+offset, pErrorCode);
+        offset=nextOffset;
+
+        /* swap the uint16_t extraData[] */
+        nextOffset=indexes[Normalizer2Impl::IX_EXTRA_DATA_OFFSET+1];
+        ds->swapArray16(ds, inBytes+offset, nextOffset-offset, outBytes+offset, pErrorCode);
+        offset=nextOffset;
+
+        U_ASSERT(offset==size);
+    }
+
+    return headerSize+size;
+}
+
+#endif  // !UCONFIG_NO_NORMALIZATION
diff --git a/icu/source/common/normalizer2impl.h b/icu/source/common/normalizer2impl.h
new file mode 100644
index 0000000..d407222
--- /dev/null
+++ b/icu/source/common/normalizer2impl.h
@@ -0,0 +1,707 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2009-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  normalizer2impl.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2009nov22
+*   created by: Markus W. Scherer
+*/
+
+#ifndef __NORMALIZER2IMPL_H__
+#define __NORMALIZER2IMPL_H__
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_NORMALIZATION
+
+#include "unicode/normalizer2.h"
+#include "unicode/udata.h"
+#include "unicode/unistr.h"
+#include "unicode/unorm.h"
+#include "mutex.h"
+#include "uset_imp.h"
+#include "utrie2.h"
+
+U_NAMESPACE_BEGIN
+
+class Hangul {
+public:
+    /* Korean Hangul and Jamo constants */
+    enum {
+        JAMO_L_BASE=0x1100,     /* "lead" jamo */
+        JAMO_V_BASE=0x1161,     /* "vowel" jamo */
+        JAMO_T_BASE=0x11a7,     /* "trail" jamo */
+
+        HANGUL_BASE=0xac00,
+
+        JAMO_L_COUNT=19,
+        JAMO_V_COUNT=21,
+        JAMO_T_COUNT=28,
+
+        JAMO_VT_COUNT=JAMO_V_COUNT*JAMO_T_COUNT,
+
+        HANGUL_COUNT=JAMO_L_COUNT*JAMO_V_COUNT*JAMO_T_COUNT,
+        HANGUL_LIMIT=HANGUL_BASE+HANGUL_COUNT
+    };
+
+    static inline UBool isHangul(UChar32 c) {
+        return HANGUL_BASE<=c && c<HANGUL_LIMIT;
+    }
+    static inline UBool
+    isHangulWithoutJamoT(UChar c) {
+        c-=HANGUL_BASE;
+        return c<HANGUL_COUNT && c%JAMO_T_COUNT==0;
+    }
+    static inline UBool isJamoL(UChar32 c) {
+        return (uint32_t)(c-JAMO_L_BASE)<JAMO_L_COUNT;
+    }
+    static inline UBool isJamoV(UChar32 c) {
+        return (uint32_t)(c-JAMO_V_BASE)<JAMO_V_COUNT;
+    }
+
+    /**
+     * Decomposes c, which must be a Hangul syllable, into buffer
+     * and returns the length of the decomposition (2 or 3).
+     */
+    static inline int32_t decompose(UChar32 c, UChar buffer[3]) {
+        c-=HANGUL_BASE;
+        UChar32 c2=c%JAMO_T_COUNT;
+        c/=JAMO_T_COUNT;
+        buffer[0]=(UChar)(JAMO_L_BASE+c/JAMO_V_COUNT);
+        buffer[1]=(UChar)(JAMO_V_BASE+c%JAMO_V_COUNT);
+        if(c2==0) {
+            return 2;
+        } else {
+            buffer[2]=(UChar)(JAMO_T_BASE+c2);
+            return 3;
+        }
+    }
+private:
+    Hangul();  // no instantiation
+};
+
+class Normalizer2Impl;
+
+class ReorderingBuffer : public UMemory {
+public:
+    ReorderingBuffer(const Normalizer2Impl &ni, UnicodeString &dest) :
+        impl(ni), str(dest),
+        start(NULL), reorderStart(NULL), limit(NULL),
+        remainingCapacity(0), lastCC(0) {}
+    ~ReorderingBuffer() {
+        if(start!=NULL) {
+            str.releaseBuffer((int32_t)(limit-start));
+        }
+    }
+    UBool init(int32_t destCapacity, UErrorCode &errorCode);
+
+    UBool isEmpty() const { return start==limit; }
+    int32_t length() const { return (int32_t)(limit-start); }
+    UChar *getStart() { return start; }
+    UChar *getLimit() { return limit; }
+    uint8_t getLastCC() const { return lastCC; }
+
+    UBool equals(const UChar *start, const UChar *limit) const;
+
+    // For Hangul composition, replacing the Leading consonant Jamo with the syllable.
+    void setLastChar(UChar c) {
+        *(limit-1)=c;
+    }
+
+    UBool append(UChar32 c, uint8_t cc, UErrorCode &errorCode) {
+        return (c<=0xffff) ?
+            appendBMP((UChar)c, cc, errorCode) :
+            appendSupplementary(c, cc, errorCode);
+    }
+    // s must be in NFD, otherwise change the implementation.
+    UBool append(const UChar *s, int32_t length,
+                 uint8_t leadCC, uint8_t trailCC,
+                 UErrorCode &errorCode);
+    UBool appendBMP(UChar c, uint8_t cc, UErrorCode &errorCode) {
+        if(remainingCapacity==0 && !resize(1, errorCode)) {
+            return FALSE;
+        }
+        if(lastCC<=cc || cc==0) {
+            *limit++=c;
+            lastCC=cc;
+            if(cc<=1) {
+                reorderStart=limit;
+            }
+        } else {
+            insert(c, cc);
+        }
+        --remainingCapacity;
+        return TRUE;
+    }
+    UBool appendZeroCC(UChar32 c, UErrorCode &errorCode);
+    UBool appendZeroCC(const UChar *s, const UChar *sLimit, UErrorCode &errorCode);
+    void remove();
+    void removeSuffix(int32_t suffixLength);
+    void setReorderingLimit(UChar *newLimit) {
+        remainingCapacity+=(int32_t)(limit-newLimit);
+        reorderStart=limit=newLimit;
+        lastCC=0;
+    }
+private:
+    /*
+     * TODO: Revisit whether it makes sense to track reorderStart.
+     * It is set to after the last known character with cc<=1,
+     * which stops previousCC() before it reads that character and looks up its cc.
+     * previousCC() is normally only called from insert().
+     * In other words, reorderStart speeds up the insertion of a combining mark
+     * into a multi-combining mark sequence where it does not belong at the end.
+     * This might not be worth the trouble.
+     * On the other hand, it's not a huge amount of trouble.
+     *
+     * We probably need it for UNORM_SIMPLE_APPEND.
+     */
+
+    UBool appendSupplementary(UChar32 c, uint8_t cc, UErrorCode &errorCode);
+    void insert(UChar32 c, uint8_t cc);
+    static void writeCodePoint(UChar *p, UChar32 c) {
+        if(c<=0xffff) {
+            *p=(UChar)c;
+        } else {
+            p[0]=U16_LEAD(c);
+            p[1]=U16_TRAIL(c);
+        }
+    }
+    UBool resize(int32_t appendLength, UErrorCode &errorCode);
+
+    const Normalizer2Impl &impl;
+    UnicodeString &str;
+    UChar *start, *reorderStart, *limit;
+    int32_t remainingCapacity;
+    uint8_t lastCC;
+
+    // private backward iterator
+    void setIterator() { codePointStart=limit; }
+    void skipPrevious();  // Requires start<codePointStart.
+    uint8_t previousCC();  // Returns 0 if there is no previous character.
+
+    UChar *codePointStart, *codePointLimit;
+};
+
+class U_COMMON_API Normalizer2Impl : public UMemory {
+public:
+    Normalizer2Impl() : memory(NULL), normTrie(NULL) {
+        fcdTrieSingleton.fInstance=NULL;
+    }
+    ~Normalizer2Impl();
+
+    void load(const char *packageName, const char *name, UErrorCode &errorCode);
+
+    void addPropertyStarts(const USetAdder *sa, UErrorCode &errorCode) const;
+
+    // low-level properties ------------------------------------------------ ***
+
+    const UTrie2 *getNormTrie() const { return normTrie; }
+    const UTrie2 *getFCDTrie(UErrorCode &errorCode) const ;
+
+    uint16_t getNorm16(UChar32 c) const { return UTRIE2_GET16(normTrie, c); }
+
+    UNormalizationCheckResult getCompQuickCheck(uint16_t norm16) const {
+        if(norm16<minNoNo || MIN_YES_YES_WITH_CC<=norm16) {
+            return UNORM_YES;
+        } else if(minMaybeYes<=norm16) {
+            return UNORM_MAYBE;
+        } else {
+            return UNORM_NO;
+        }
+    }
+    UBool isCompNo(uint16_t norm16) const { return minNoNo<=norm16 && norm16<minMaybeYes; }
+    UBool isDecompYes(uint16_t norm16) const { return norm16<minYesNo || minMaybeYes<=norm16; }
+
+    uint8_t getCC(uint16_t norm16) const {
+        if(norm16>=MIN_NORMAL_MAYBE_YES) {
+            return (uint8_t)norm16;
+        }
+        if(norm16<minNoNo || limitNoNo<=norm16) {
+            return 0;
+        }
+        return getCCFromNoNo(norm16);
+    }
+    static uint8_t getCCFromYesOrMaybe(uint16_t norm16) {
+        return norm16>=MIN_NORMAL_MAYBE_YES ? (uint8_t)norm16 : 0;
+    }
+
+    uint16_t getFCD16(UChar32 c) const { return UTRIE2_GET16(fcdTrie(), c); }
+    uint16_t getFCD16FromSingleLead(UChar c) const {
+        return UTRIE2_GET16_FROM_U16_SINGLE_LEAD(fcdTrie(), c);
+    }
+    uint16_t getFCD16FromSupplementary(UChar32 c) const {
+        return UTRIE2_GET16_FROM_SUPP(fcdTrie(), c);
+    }
+    uint16_t getFCD16FromSurrogatePair(UChar c, UChar c2) const {
+        return getFCD16FromSupplementary(U16_GET_SUPPLEMENTARY(c, c2));
+    }
+
+    void setFCD16FromNorm16(UChar32 start, UChar32 end, uint16_t norm16,
+                            UTrie2 *newFCDTrie, UErrorCode &errorCode) const;
+
+    /**
+     * Get the decomposition for one code point.
+     * @param c code point
+     * @param buffer out-only buffer for algorithmic decompositions
+     * @param length out-only, takes the length of the decomposition, if any
+     * @return pointer to the decomposition, or NULL if none
+     */
+    const UChar *getDecomposition(UChar32 c, UChar buffer[4], int32_t &length) const;
+
+    enum {
+        MIN_CCC_LCCC_CP=0x300
+    };
+
+    enum {
+        MIN_YES_YES_WITH_CC=0xff01,
+        JAMO_VT=0xff00,
+        MIN_NORMAL_MAYBE_YES=0xfe00,
+        JAMO_L=1,
+        MAX_DELTA=0x40
+    };
+
+    enum {
+        // Byte offsets from the start of the data, after the generic header.
+        IX_NORM_TRIE_OFFSET,
+        IX_EXTRA_DATA_OFFSET,
+        IX_RESERVED2_OFFSET,
+        IX_RESERVED3_OFFSET,
+        IX_RESERVED4_OFFSET,
+        IX_RESERVED5_OFFSET,
+        IX_RESERVED6_OFFSET,
+        IX_TOTAL_SIZE,
+
+        // Code point thresholds for quick check codes.
+        IX_MIN_DECOMP_NO_CP,
+        IX_MIN_COMP_NO_MAYBE_CP,
+
+        // Norm16 value thresholds for quick check combinations and types of extra data.
+        IX_MIN_YES_NO,
+        IX_MIN_NO_NO,
+        IX_LIMIT_NO_NO,
+        IX_MIN_MAYBE_YES,
+
+        IX_RESERVED14,
+        IX_RESERVED15,
+        IX_COUNT
+    };
+
+    enum {
+        MAPPING_HAS_CCC_LCCC_WORD=0x80,
+        MAPPING_PLUS_COMPOSITION_LIST=0x40,
+        MAPPING_NO_COMP_BOUNDARY_AFTER=0x20,
+        MAPPING_LENGTH_MASK=0x1f
+    };
+
+    enum {
+        COMP_1_LAST_TUPLE=0x8000,
+        COMP_1_TRIPLE=1,
+        COMP_1_TRAIL_LIMIT=0x3400,
+        COMP_1_TRAIL_MASK=0x7ffe,
+        COMP_1_TRAIL_SHIFT=9,  // 10-1 for the "triple" bit
+        COMP_2_TRAIL_SHIFT=6,
+        COMP_2_TRAIL_MASK=0xffc0
+    };
+
+    // higher-level functionality ------------------------------------------ ***
+
+    const UChar *decompose(const UChar *src, const UChar *limit,
+                           ReorderingBuffer *buffer, UErrorCode &errorCode) const;
+    void decomposeAndAppend(const UChar *src, const UChar *limit,
+                            UBool doDecompose,
+                            ReorderingBuffer &buffer,
+                            UErrorCode &errorCode) const;
+    UBool compose(const UChar *src, const UChar *limit,
+                  UBool onlyContiguous,
+                  UBool doCompose,
+                  ReorderingBuffer &buffer,
+                  UErrorCode &errorCode) const;
+    const UChar *composeQuickCheck(const UChar *src, const UChar *limit,
+                                   UBool onlyContiguous,
+                                   UNormalizationCheckResult *pQCResult) const;
+    void composeAndAppend(const UChar *src, const UChar *limit,
+                          UBool doCompose,
+                          UBool onlyContiguous,
+                          ReorderingBuffer &buffer,
+                          UErrorCode &errorCode) const;
+    const UChar *makeFCD(const UChar *src, const UChar *limit,
+                         ReorderingBuffer *buffer, UErrorCode &errorCode) const;
+    void makeFCDAndAppend(const UChar *src, const UChar *limit,
+                          UBool doMakeFCD,
+                          ReorderingBuffer &buffer,
+                          UErrorCode &errorCode) const;
+
+    UBool hasDecompBoundary(UChar32 c, UBool before) const;
+    UBool isDecompInert(UChar32 c) const { return isDecompYesAndZeroCC(getNorm16(c)); }
+
+    UBool hasCompBoundaryBefore(UChar32 c) const {
+        return c<minCompNoMaybeCP || hasCompBoundaryBefore(c, getNorm16(c));
+    }
+    UBool hasCompBoundaryAfter(UChar32 c, UBool onlyContiguous, UBool testInert) const;
+
+    UBool hasFCDBoundaryBefore(UChar32 c) const { return c<MIN_CCC_LCCC_CP || getFCD16(c)<=0xff; }
+    UBool hasFCDBoundaryAfter(UChar32 c) const {
+        uint16_t fcd16=getFCD16(c);
+        return fcd16<=1 || (fcd16&0xff)==0;
+    }
+    UBool isFCDInert(UChar32 c) const { return getFCD16(c)<=1; }
+private:
+    static UBool U_CALLCONV
+    isAcceptable(void *context, const char *type, const char *name, const UDataInfo *pInfo);
+
+    UBool isMaybe(uint16_t norm16) const { return minMaybeYes<=norm16 && norm16<=JAMO_VT; }
+    UBool isMaybeOrNonZeroCC(uint16_t norm16) const { return norm16>=minMaybeYes; }
+    static UBool isInert(uint16_t norm16) { return norm16==0; }
+    // static UBool isJamoL(uint16_t norm16) const { return norm16==1; }
+    static UBool isJamoVT(uint16_t norm16) { return norm16==JAMO_VT; }
+    UBool isHangul(uint16_t norm16) const { return norm16==minYesNo; }
+    UBool isCompYesAndZeroCC(uint16_t norm16) const { return norm16<minNoNo; }
+    // UBool isCompYes(uint16_t norm16) const {
+    //     return norm16>=MIN_YES_YES_WITH_CC || norm16<minNoNo;
+    // }
+    // UBool isCompYesOrMaybe(uint16_t norm16) const {
+    //     return norm16<minNoNo || minMaybeYes<=norm16;
+    // }
+    // UBool hasZeroCCFromDecompYes(uint16_t norm16) const {
+    //     return norm16<=MIN_NORMAL_MAYBE_YES || norm16==JAMO_VT;
+    // }
+    UBool isDecompYesAndZeroCC(uint16_t norm16) const {
+        return norm16<minYesNo ||
+               norm16==JAMO_VT ||
+               (minMaybeYes<=norm16 && norm16<=MIN_NORMAL_MAYBE_YES);
+    }
+    /**
+     * A little faster and simpler than isDecompYesAndZeroCC() but does not include
+     * the MaybeYes which combine-forward and have ccc=0.
+     * (Standard Unicode 5.2 normalization does not have such characters.)
+     */
+    UBool isMostDecompYesAndZeroCC(uint16_t norm16) const {
+        return norm16<minYesNo || norm16==MIN_NORMAL_MAYBE_YES || norm16==JAMO_VT;
+    }
+    UBool isDecompNoAlgorithmic(uint16_t norm16) const { return norm16>=limitNoNo; }
+
+    // For use with isCompYes().
+    // Perhaps the compiler can combine the two tests for MIN_YES_YES_WITH_CC.
+    // static uint8_t getCCFromYes(uint16_t norm16) {
+    //     return norm16>=MIN_YES_YES_WITH_CC ? (uint8_t)norm16 : 0;
+    // }
+    uint8_t getCCFromNoNo(uint16_t norm16) const {
+        const uint16_t *mapping=getMapping(norm16);
+        if(*mapping&MAPPING_HAS_CCC_LCCC_WORD) {
+            return (uint8_t)mapping[1];
+        } else {
+            return 0;
+        }
+    }
+    // requires that the [cpStart..cpLimit[ character passes isCompYesAndZeroCC()
+    uint8_t getTrailCCFromCompYesAndZeroCC(const UChar *cpStart, const UChar *cpLimit) const;
+
+    // Requires algorithmic-NoNo.
+    UChar32 mapAlgorithmic(UChar32 c, uint16_t norm16) const {
+        return c+norm16-(minMaybeYes-MAX_DELTA-1);
+    }
+
+    // Requires minYesNo<norm16<limitNoNo.
+    const uint16_t *getMapping(uint16_t norm16) const { return extraData+norm16; }
+    const uint16_t *getCompositionsListForDecompYes(uint16_t norm16) const {
+        if(norm16==0 || MIN_NORMAL_MAYBE_YES<=norm16) {
+            return NULL;
+        } else if(norm16<minMaybeYes) {
+            return extraData+norm16;  // for yesYes; if Jamo L: harmless empty list
+        } else {
+            return maybeYesCompositions+norm16-minMaybeYes;
+        }
+    }
+    const uint16_t *getCompositionsListForComposite(uint16_t norm16) const {
+        const uint16_t *list=extraData+norm16;  // composite has both mapping & compositions list
+        return list+  // mapping pointer
+            1+  // +1 to skip the first unit with the mapping lenth
+            (*list&MAPPING_LENGTH_MASK)+  // + mapping length
+            ((*list>>7)&1);  // +1 if MAPPING_HAS_CCC_LCCC_WORD
+    }
+
+    const UChar *copyLowPrefixFromNulTerminated(const UChar *src,
+                                                UChar32 minNeedDataCP,
+                                                ReorderingBuffer *buffer,
+                                                UErrorCode &errorCode) const;
+    UBool decomposeShort(const UChar *src, const UChar *limit,
+                         ReorderingBuffer &buffer, UErrorCode &errorCode) const;
+    UBool decompose(UChar32 c, uint16_t norm16,
+                    ReorderingBuffer &buffer, UErrorCode &errorCode) const;
+
+    static int32_t combine(const uint16_t *list, UChar32 trail);
+    void recompose(ReorderingBuffer &buffer, int32_t recomposeStartIndex,
+                   UBool onlyContiguous) const;
+
+    UBool hasCompBoundaryBefore(UChar32 c, uint16_t norm16) const;
+    const UChar *findPreviousCompBoundary(const UChar *start, const UChar *p) const;
+    const UChar *findNextCompBoundary(const UChar *p, const UChar *limit) const;
+
+    const UTrie2 *fcdTrie() const { return (const UTrie2 *)fcdTrieSingleton.fInstance; }
+
+    const UChar *findPreviousFCDBoundary(const UChar *start, const UChar *p) const;
+    const UChar *findNextFCDBoundary(const UChar *p, const UChar *limit) const;
+
+    UDataMemory *memory;
+    UVersionInfo dataVersion;
+
+    // Code point thresholds for quick check codes.
+    UChar32 minDecompNoCP;
+    UChar32 minCompNoMaybeCP;
+
+    // Norm16 value thresholds for quick check combinations and types of extra data.
+    uint16_t minYesNo;
+    uint16_t minNoNo;
+    uint16_t limitNoNo;
+    uint16_t minMaybeYes;
+
+    UTrie2 *normTrie;
+    const uint16_t *maybeYesCompositions;
+    const uint16_t *extraData;  // mappings and/or compositions for yesYes, yesNo & noNo characters
+
+    SimpleSingleton fcdTrieSingleton;
+};
+
+/**
+ * ICU-internal shortcut for quick access to standard Unicode normalization.
+ */
+class U_COMMON_API Normalizer2Factory {
+public:
+    static const Normalizer2 *getNFCInstance(UErrorCode &errorCode);
+    static const Normalizer2 *getNFDInstance(UErrorCode &errorCode);
+    static const Normalizer2 *getFCDInstance(UErrorCode &errorCode);
+    static const Normalizer2 *getFCCInstance(UErrorCode &errorCode);
+    static const Normalizer2 *getNFKCInstance(UErrorCode &errorCode);
+    static const Normalizer2 *getNFKDInstance(UErrorCode &errorCode);
+    static const Normalizer2 *getNFKC_CFInstance(UErrorCode &errorCode);
+    static const Normalizer2 *getNoopInstance(UErrorCode &errorCode);
+
+    static const Normalizer2 *getInstance(UNormalizationMode mode, UErrorCode &errorCode);
+
+    static const Normalizer2Impl *getNFCImpl(UErrorCode &errorCode);
+    static const Normalizer2Impl *getNFKCImpl(UErrorCode &errorCode);
+    static const Normalizer2Impl *getNFKC_CFImpl(UErrorCode &errorCode);
+
+    // Get the Impl instance of the Normalizer2.
+    // Must be used only when it is known that norm2 is a Normalizer2WithImpl instance.
+    static const Normalizer2Impl *getImpl(const Normalizer2 *norm2);
+
+    static const UTrie2 *getFCDTrie(UErrorCode &errorCode);
+private:
+    Normalizer2Factory();  // No instantiation.
+};
+
+U_NAMESPACE_END
+
+U_CAPI int32_t U_EXPORT2
+unorm2_swap(const UDataSwapper *ds,
+            const void *inData, int32_t length, void *outData,
+            UErrorCode *pErrorCode);
+
+/**
+ * Get the NF*_QC property for a code point, for u_getIntPropertyValue().
+ * @internal
+ */
+U_CFUNC UNormalizationCheckResult U_EXPORT2
+unorm_getQuickCheck(UChar32 c, UNormalizationMode mode);
+
+/**
+ * Internal API, used by collation code.
+ * Get access to the internal FCD trie table to be able to perform
+ * incremental, per-code unit, FCD checks in collation.
+ * One pointer is sufficient because the trie index values are offset
+ * by the index size, so that the same pointer is used to access the trie data.
+ * Code points at fcdHighStart and above have a zero FCD value.
+ * @internal
+ */
+U_CAPI const uint16_t * U_EXPORT2
+unorm_getFCDTrieIndex(UChar32 &fcdHighStart, UErrorCode *pErrorCode);
+
+/**
+ * Internal API, used by collation code.
+ * Get the FCD value for a code unit, with
+ * bits 15..8   lead combining class
+ * bits  7..0   trail combining class
+ *
+ * If c is a lead surrogate and the value is not 0,
+ * then some of c's associated supplementary code points have a non-zero FCD value.
+ *
+ * @internal
+ */
+static inline uint16_t
+unorm_getFCD16(const uint16_t *fcdTrieIndex, UChar c) {
+    return fcdTrieIndex[_UTRIE2_INDEX_FROM_U16_SINGLE_LEAD(fcdTrieIndex, c)];
+}
+
+/**
+ * Internal API, used by collation code.
+ * Get the FCD value of the next code point (post-increment), with
+ * bits 15..8   lead combining class
+ * bits  7..0   trail combining class
+ *
+ * @internal
+ */
+static inline uint16_t
+unorm_nextFCD16(const uint16_t *fcdTrieIndex, UChar32 fcdHighStart,
+                const UChar *&s, const UChar *limit) {
+    UChar32 c=*s++;
+    uint16_t fcd=fcdTrieIndex[_UTRIE2_INDEX_FROM_U16_SINGLE_LEAD(fcdTrieIndex, c)];
+    if(fcd!=0 && U16_IS_LEAD(c)) {
+        UChar c2;
+        if(s!=limit && U16_IS_TRAIL(c2=*s)) {
+            ++s;
+            c=U16_GET_SUPPLEMENTARY(c, c2);
+            if(c<fcdHighStart) {
+                fcd=fcdTrieIndex[_UTRIE2_INDEX_FROM_SUPP(fcdTrieIndex, c)];
+            } else {
+                fcd=0;
+            }
+        } else /* unpaired lead surrogate */ {
+            fcd=0;
+        }
+    }
+    return fcd;
+}
+
+/**
+ * Internal API, used by collation code.
+ * Get the FCD value of the previous code point (pre-decrement), with
+ * bits 15..8   lead combining class
+ * bits  7..0   trail combining class
+ *
+ * @internal
+ */
+static inline uint16_t
+unorm_prevFCD16(const uint16_t *fcdTrieIndex, UChar32 fcdHighStart,
+                const UChar *start, const UChar *&s) {
+    UChar32 c=*--s;
+    uint16_t fcd;
+    if(!U16_IS_SURROGATE(c)) {
+        fcd=fcdTrieIndex[_UTRIE2_INDEX_FROM_U16_SINGLE_LEAD(fcdTrieIndex, c)];
+    } else {
+        UChar c2;
+        if(U16_IS_SURROGATE_TRAIL(c) && s!=start && U16_IS_LEAD(c2=*(s-1))) {
+            --s;
+            c=U16_GET_SUPPLEMENTARY(c2, c);
+            if(c<fcdHighStart) {
+                fcd=fcdTrieIndex[_UTRIE2_INDEX_FROM_SUPP(fcdTrieIndex, c)];
+            } else {
+                fcd=0;
+            }
+        } else /* unpaired surrogate */ {
+            fcd=0;
+        }
+    }
+    return fcd;
+}
+
+/**
+ * Format of Normalizer2 .nrm data files.
+ * Format version 1.0.
+ *
+ * Normalizer2 .nrm data files provide data for the Unicode Normalization algorithms.
+ * ICU ships with data files for standard Unicode Normalization Forms
+ * NFC and NFD (nfc.nrm), NFKC and NFKD (nfkc.nrm) and NFKC_Casefold (nfkc_cf.nrm).
+ * Custom (application-specific) data can be built into additional .nrm files
+ * with the gennorm2 build tool.
+ *
+ * Normalizer2.getInstance() causes a .nrm file to be loaded, unless it has been
+ * cached already. Internally, Normalizer2Impl.load() reads the .nrm file.
+ *
+ * A .nrm file begins with a standard ICU data file header
+ * (DataHeader, see ucmndata.h and unicode/udata.h).
+ * The UDataInfo.dataVersion field usually contains the Unicode version
+ * for which the data was generated.
+ *
+ * After the header, the file contains the following parts.
+ * Constants are defined as enum values of the Normalizer2Impl class.
+ *
+ * Many details of the data structures are described in the design doc
+ * which is at http://site.icu-project.org/design/normalization/custom
+ *
+ * int32_t indexes[indexesLength]; -- indexesLength=indexes[IX_NORM_TRIE_OFFSET]/4;
+ *
+ *      The first eight indexes are byte offsets in ascending order.
+ *      Each byte offset marks the start of the next part in the data file,
+ *      and the end of the previous one.
+ *      When two consecutive byte offsets are the same, then the corresponding part is empty.
+ *      Byte offsets are offsets from after the header,
+ *      that is, from the beginning of the indexes[].
+ *      Each part starts at an offset with proper alignment for its data.
+ *      If necessary, the previous part may include padding bytes to achieve this alignment.
+ *
+ *      minDecompNoCP=indexes[IX_MIN_DECOMP_NO_CP] is the lowest code point
+ *      with a decomposition mapping, that is, with NF*D_QC=No.
+ *      minCompNoMaybeCP=indexes[IX_MIN_COMP_NO_MAYBE_CP] is the lowest code point
+ *      with NF*C_QC=No (has a one-way mapping) or Maybe (combines backward).
+ *
+ *      The next four indexes are thresholds of 16-bit trie values for ranges of
+ *      values indicating multiple normalization properties.
+ *          minYesNo=indexes[IX_MIN_YES_NO];
+ *          minNoNo=indexes[IX_MIN_NO_NO];
+ *          limitNoNo=indexes[IX_LIMIT_NO_NO];
+ *          minMaybeYes=indexes[IX_MIN_MAYBE_YES];
+ *      See the normTrie description below and the design doc for details.
+ *
+ * UTrie2 normTrie; -- see utrie2_impl.h and utrie2.h
+ *
+ *      The trie holds the main normalization data. Each code point is mapped to a 16-bit value.
+ *      Rather than using independent bits in the value (which would require more than 16 bits),
+ *      information is extracted primarily via range checks.
+ *      For example, a 16-bit value norm16 in the range minYesNo<=norm16<minNoNo
+ *      means that the character has NF*C_QC=Yes and NF*D_QC=No properties,
+ *      which means it has a two-way (round-trip) decomposition mapping.
+ *      Values in the range 2<=norm16<limitNoNo are also directly indexes into the extraData
+ *      pointing to mappings, composition lists, or both.
+ *      Value norm16==0 means that the character is normalization-inert, that is,
+ *      it does not have a mapping, does not participate in composition, has a zero
+ *      canonical combining class, and forms a boundary where text before it and after it
+ *      can be normalized independently.
+ *      For details about how multiple properties are encoded in 16-bit values
+ *      see the design doc.
+ *      Note that the encoding cannot express all combinations of the properties involved;
+ *      it only supports those combinations that are allowed by
+ *      the Unicode Normalization algorithms. Details are in the design doc as well.
+ *      The gennorm2 tool only builds .nrm files for data that conforms to the limitations.
+ *
+ *      The trie has a value for each lead surrogate code unit representing the "worst case"
+ *      properties of the 1024 supplementary characters whose UTF-16 form starts with
+ *      the lead surrogate. If all of the 1024 supplementary characters are normalization-inert,
+ *      then their lead surrogate code unit has the trie value 0.
+ *      When the lead surrogate unit's value exceeds the quick check minimum during processing,
+ *      the properties for the full supplementary code point need to be looked up.
+ *
+ * uint16_t maybeYesCompositions[MIN_NORMAL_MAYBE_YES-minMaybeYes];
+ * uint16_t extraData[];
+ *
+ *      There is only one byte offset for the end of these two arrays.
+ *      The split between them is given by the constant and variable mentioned above.
+ *
+ *      The maybeYesCompositions array contains composition lists for characters that
+ *      combine both forward (as starters in composition pairs)
+ *      and backward (as trailing characters in composition pairs).
+ *      Such characters do not occur in Unicode 5.2 but are allowed by
+ *      the Unicode Normalization algorithms.
+ *      If there are no such characters, then minMaybeYes==MIN_NORMAL_MAYBE_YES
+ *      and the maybeYesCompositions array is empty.
+ *      If there are such characters, then minMaybeYes is subtracted from their norm16 values
+ *      to get the index into this array.
+ *
+ *      The extraData array contains composition lists for "YesYes" characters,
+ *      followed by mappings and optional composition lists for "YesNo" characters,
+ *      followed by only mappings for "NoNo" characters.
+ *      (Referring to pairs of NFC/NFD quick check values.)
+ *      The norm16 values of those characters are directly indexes into the extraData array.
+ *
+ *      The data structures for composition lists and mappings are described in the design doc.
+ */
+
+#endif  /* !UCONFIG_NO_NORMALIZATION */
+#endif  /* __NORMALIZER2IMPL_H__ */
diff --git a/icu/source/common/normlzr.cpp b/icu/source/common/normlzr.cpp
new file mode 100644
index 0000000..1de466a
--- /dev/null
+++ b/icu/source/common/normlzr.cpp
@@ -0,0 +1,522 @@
+/*
+ *************************************************************************
+ * COPYRIGHT: 
+ * Copyright (c) 1996-2010, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ *************************************************************************
+ */
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_NORMALIZATION
+
+#include "unicode/uniset.h"
+#include "unicode/unistr.h"
+#include "unicode/chariter.h"
+#include "unicode/schriter.h"
+#include "unicode/uchriter.h"
+#include "unicode/normlzr.h"
+#include "cmemory.h"
+#include "normalizer2impl.h"
+#include "uprops.h"  // for uniset_getUnicode32Instance()
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Normalizer)
+
+//-------------------------------------------------------------------------
+// Constructors and other boilerplate
+//-------------------------------------------------------------------------
+
+Normalizer::Normalizer(const UnicodeString& str, UNormalizationMode mode) :
+    UObject(), fFilteredNorm2(NULL), fNorm2(NULL), fUMode(mode), fOptions(0),
+    text(new StringCharacterIterator(str)),
+    currentIndex(0), nextIndex(0),
+    buffer(), bufferPos(0)
+{
+    init();
+}
+
+Normalizer::Normalizer(const UChar *str, int32_t length, UNormalizationMode mode) :
+    UObject(), fFilteredNorm2(NULL), fNorm2(NULL), fUMode(mode), fOptions(0),
+    text(new UCharCharacterIterator(str, length)),
+    currentIndex(0), nextIndex(0),
+    buffer(), bufferPos(0)
+{
+    init();
+}
+
+Normalizer::Normalizer(const CharacterIterator& iter, UNormalizationMode mode) :
+    UObject(), fFilteredNorm2(NULL), fNorm2(NULL), fUMode(mode), fOptions(0),
+    text(iter.clone()),
+    currentIndex(0), nextIndex(0),
+    buffer(), bufferPos(0)
+{
+    init();
+}
+
+Normalizer::Normalizer(const Normalizer &copy) :
+    UObject(copy), fFilteredNorm2(NULL), fNorm2(NULL), fUMode(copy.fUMode), fOptions(copy.fOptions),
+    text(copy.text->clone()),
+    currentIndex(copy.currentIndex), nextIndex(copy.nextIndex),
+    buffer(copy.buffer), bufferPos(copy.bufferPos)
+{
+    init();
+}
+
+static const UChar _NUL=0;
+
+void
+Normalizer::init() {
+    UErrorCode errorCode=U_ZERO_ERROR;
+    fNorm2=Normalizer2Factory::getInstance(fUMode, errorCode);
+    if(fOptions&UNORM_UNICODE_3_2) {
+        delete fFilteredNorm2;
+        fNorm2=fFilteredNorm2=
+            new FilteredNormalizer2(*fNorm2, *uniset_getUnicode32Instance(errorCode));
+    }
+    if(U_FAILURE(errorCode)) {
+        errorCode=U_ZERO_ERROR;
+        fNorm2=Normalizer2Factory::getNoopInstance(errorCode);
+    }
+}
+
+Normalizer::~Normalizer()
+{
+    delete fFilteredNorm2;
+    delete text;
+}
+
+Normalizer* 
+Normalizer::clone() const
+{
+    return new Normalizer(*this);
+}
+
+/**
+ * Generates a hash code for this iterator.
+ */
+int32_t Normalizer::hashCode() const
+{
+    return text->hashCode() + fUMode + fOptions + buffer.hashCode() + bufferPos + currentIndex + nextIndex;
+}
+    
+UBool Normalizer::operator==(const Normalizer& that) const
+{
+    return
+        this==&that ||
+        fUMode==that.fUMode &&
+        fOptions==that.fOptions &&
+        *text==*that.text &&
+        buffer==that.buffer &&
+        bufferPos==that.bufferPos &&
+        nextIndex==that.nextIndex;
+}
+
+//-------------------------------------------------------------------------
+// Static utility methods
+//-------------------------------------------------------------------------
+
+void U_EXPORT2
+Normalizer::normalize(const UnicodeString& source, 
+                      UNormalizationMode mode, int32_t options,
+                      UnicodeString& result, 
+                      UErrorCode &status) {
+    if(source.isBogus() || U_FAILURE(status)) {
+        result.setToBogus();
+        if(U_SUCCESS(status)) {
+            status=U_ILLEGAL_ARGUMENT_ERROR;
+        }
+    } else {
+        UnicodeString localDest;
+        UnicodeString *dest;
+
+        if(&source!=&result) {
+            dest=&result;
+        } else {
+            // the source and result strings are the same object, use a temporary one
+            dest=&localDest;
+        }
+        const Normalizer2 *n2=Normalizer2Factory::getInstance(mode, status);
+        if(U_SUCCESS(status)) {
+            if(options&UNORM_UNICODE_3_2) {
+                FilteredNormalizer2(*n2, *uniset_getUnicode32Instance(status)).
+                    normalize(source, *dest, status);
+            } else {
+                n2->normalize(source, *dest, status);
+            }
+        }
+        if(dest==&localDest && U_SUCCESS(status)) {
+            result=*dest;
+        }
+    }
+}
+
+void U_EXPORT2
+Normalizer::compose(const UnicodeString& source, 
+                    UBool compat, int32_t options,
+                    UnicodeString& result, 
+                    UErrorCode &status) {
+    normalize(source, compat ? UNORM_NFKC : UNORM_NFC, options, result, status);
+}
+
+void U_EXPORT2
+Normalizer::decompose(const UnicodeString& source, 
+                      UBool compat, int32_t options,
+                      UnicodeString& result, 
+                      UErrorCode &status) {
+    normalize(source, compat ? UNORM_NFKD : UNORM_NFD, options, result, status);
+}
+
+UNormalizationCheckResult
+Normalizer::quickCheck(const UnicodeString& source,
+                       UNormalizationMode mode, int32_t options,
+                       UErrorCode &status) {
+    const Normalizer2 *n2=Normalizer2Factory::getInstance(mode, status);
+    if(U_SUCCESS(status)) {
+        if(options&UNORM_UNICODE_3_2) {
+            return FilteredNormalizer2(*n2, *uniset_getUnicode32Instance(status)).
+                quickCheck(source, status);
+        } else {
+            return n2->quickCheck(source, status);
+        }
+    } else {
+        return UNORM_MAYBE;
+    }
+}
+
+UBool
+Normalizer::isNormalized(const UnicodeString& source,
+                         UNormalizationMode mode, int32_t options,
+                         UErrorCode &status) {
+    const Normalizer2 *n2=Normalizer2Factory::getInstance(mode, status);
+    if(U_SUCCESS(status)) {
+        if(options&UNORM_UNICODE_3_2) {
+            return FilteredNormalizer2(*n2, *uniset_getUnicode32Instance(status)).
+                isNormalized(source, status);
+        } else {
+            return n2->isNormalized(source, status);
+        }
+    } else {
+        return FALSE;
+    }
+}
+
+UnicodeString & U_EXPORT2
+Normalizer::concatenate(UnicodeString &left, UnicodeString &right,
+                        UnicodeString &result,
+                        UNormalizationMode mode, int32_t options,
+                        UErrorCode &errorCode) {
+    if(left.isBogus() || right.isBogus() || U_FAILURE(errorCode)) {
+        result.setToBogus();
+        if(U_SUCCESS(errorCode)) {
+            errorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        }
+    } else {
+        UnicodeString localDest;
+        UnicodeString *dest;
+
+        if(&right!=&result) {
+            dest=&result;
+        } else {
+            // the right and result strings are the same object, use a temporary one
+            dest=&localDest;
+        }
+        *dest=left;
+        const Normalizer2 *n2=Normalizer2Factory::getInstance(mode, errorCode);
+        if(U_SUCCESS(errorCode)) {
+            if(options&UNORM_UNICODE_3_2) {
+                FilteredNormalizer2(*n2, *uniset_getUnicode32Instance(errorCode)).
+                    append(*dest, right, errorCode);
+            } else {
+                n2->append(*dest, right, errorCode);
+            }
+        }
+        if(dest==&localDest && U_SUCCESS(errorCode)) {
+            result=*dest;
+        }
+    }
+    return result;
+}
+
+//-------------------------------------------------------------------------
+// Iteration API
+//-------------------------------------------------------------------------
+
+/**
+ * Return the current character in the normalized text.
+ */
+UChar32 Normalizer::current() {
+    if(bufferPos<buffer.length() || nextNormalize()) {
+        return buffer.char32At(bufferPos);
+    } else {
+        return DONE;
+    }
+}
+
+/**
+ * Return the next character in the normalized text and advance
+ * the iteration position by one.  If the end
+ * of the text has already been reached, {@link #DONE} is returned.
+ */
+UChar32 Normalizer::next() {
+    if(bufferPos<buffer.length() ||  nextNormalize()) {
+        UChar32 c=buffer.char32At(bufferPos);
+        bufferPos+=UTF_CHAR_LENGTH(c);
+        return c;
+    } else {
+        return DONE;
+    }
+}
+
+/**
+ * Return the previous character in the normalized text and decrement
+ * the iteration position by one.  If the beginning
+ * of the text has already been reached, {@link #DONE} is returned.
+ */
+UChar32 Normalizer::previous() {
+    if(bufferPos>0 || previousNormalize()) {
+        UChar32 c=buffer.char32At(bufferPos-1);
+        bufferPos-=UTF_CHAR_LENGTH(c);
+        return c;
+    } else {
+        return DONE;
+    }
+}
+
+void Normalizer::reset() {
+    currentIndex=nextIndex=text->setToStart();
+    clearBuffer();
+}
+
+void
+Normalizer::setIndexOnly(int32_t index) {
+    text->setIndex(index);  // pins index
+    currentIndex=nextIndex=text->getIndex();
+    clearBuffer();
+}
+
+/**
+ * Return the first character in the normalized text.  This resets
+ * the <tt>Normalizer's</tt> position to the beginning of the text.
+ */
+UChar32 Normalizer::first() {
+    reset();
+    return next();
+}
+
+/**
+ * Return the last character in the normalized text.  This resets
+ * the <tt>Normalizer's</tt> position to be just before the
+ * the input text corresponding to that normalized character.
+ */
+UChar32 Normalizer::last() {
+    currentIndex=nextIndex=text->setToEnd();
+    clearBuffer();
+    return previous();
+}
+
+/**
+ * Retrieve the current iteration position in the input text that is
+ * being normalized.  This method is useful in applications such as
+ * searching, where you need to be able to determine the position in
+ * the input text that corresponds to a given normalized output character.
+ * <p>
+ * <b>Note:</b> This method sets the position in the <em>input</em>, while
+ * {@link #next} and {@link #previous} iterate through characters in the
+ * <em>output</em>.  This means that there is not necessarily a one-to-one
+ * correspondence between characters returned by <tt>next</tt> and
+ * <tt>previous</tt> and the indices passed to and returned from
+ * <tt>setIndex</tt> and {@link #getIndex}.
+ *
+ */
+int32_t Normalizer::getIndex() const {
+    if(bufferPos<buffer.length()) {
+        return currentIndex;
+    } else {
+        return nextIndex;
+    }
+}
+
+/**
+ * Retrieve the index of the start of the input text.  This is the begin index
+ * of the <tt>CharacterIterator</tt> or the start (i.e. 0) of the <tt>String</tt>
+ * over which this <tt>Normalizer</tt> is iterating
+ */
+int32_t Normalizer::startIndex() const {
+    return text->startIndex();
+}
+
+/**
+ * Retrieve the index of the end of the input text.  This is the end index
+ * of the <tt>CharacterIterator</tt> or the length of the <tt>String</tt>
+ * over which this <tt>Normalizer</tt> is iterating
+ */
+int32_t Normalizer::endIndex() const {
+    return text->endIndex();
+}
+
+//-------------------------------------------------------------------------
+// Property access methods
+//-------------------------------------------------------------------------
+
+void
+Normalizer::setMode(UNormalizationMode newMode) 
+{
+    fUMode = newMode;
+    init();
+}
+
+UNormalizationMode
+Normalizer::getUMode() const
+{
+    return fUMode;
+}
+
+void
+Normalizer::setOption(int32_t option, 
+                      UBool value) 
+{
+    if (value) {
+        fOptions |= option;
+    } else {
+        fOptions &= (~option);
+    }
+    init();
+}
+
+UBool
+Normalizer::getOption(int32_t option) const
+{
+    return (fOptions & option) != 0;
+}
+
+/**
+ * Set the input text over which this <tt>Normalizer</tt> will iterate.
+ * The iteration position is set to the beginning of the input text.
+ */
+void
+Normalizer::setText(const UnicodeString& newText, 
+                    UErrorCode &status)
+{
+    if (U_FAILURE(status)) {
+        return;
+    }
+    CharacterIterator *newIter = new StringCharacterIterator(newText);
+    if (newIter == NULL) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    delete text;
+    text = newIter;
+    reset();
+}
+
+/**
+ * Set the input text over which this <tt>Normalizer</tt> will iterate.
+ * The iteration position is set to the beginning of the string.
+ */
+void
+Normalizer::setText(const CharacterIterator& newText, 
+                    UErrorCode &status) 
+{
+    if (U_FAILURE(status)) {
+        return;
+    }
+    CharacterIterator *newIter = newText.clone();
+    if (newIter == NULL) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    delete text;
+    text = newIter;
+    reset();
+}
+
+void
+Normalizer::setText(const UChar* newText,
+                    int32_t length,
+                    UErrorCode &status)
+{
+    if (U_FAILURE(status)) {
+        return;
+    }
+    CharacterIterator *newIter = new UCharCharacterIterator(newText, length);
+    if (newIter == NULL) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    delete text;
+    text = newIter;
+    reset();
+}
+
+/**
+ * Copies the text under iteration into the UnicodeString referred to by "result".
+ * @param result Receives a copy of the text under iteration.
+ */
+void
+Normalizer::getText(UnicodeString&  result) 
+{
+    text->getText(result);
+}
+
+//-------------------------------------------------------------------------
+// Private utility methods
+//-------------------------------------------------------------------------
+
+void Normalizer::clearBuffer() {
+    buffer.remove();
+    bufferPos=0;
+}
+
+UBool
+Normalizer::nextNormalize() {
+    clearBuffer();
+    currentIndex=nextIndex;
+    text->setIndex(nextIndex);
+    if(!text->hasNext()) {
+        return FALSE;
+    }
+    // Skip at least one character so we make progress.
+    UnicodeString segment(text->next32PostInc());
+    while(text->hasNext()) {
+        UChar32 c;
+        if(fNorm2->hasBoundaryBefore(c=text->next32PostInc())) {
+            text->move32(-1, CharacterIterator::kCurrent);
+            break;
+        }
+        segment.append(c);
+    }
+    nextIndex=text->getIndex();
+    UErrorCode errorCode=U_ZERO_ERROR;
+    fNorm2->normalize(segment, buffer, errorCode);
+    return U_SUCCESS(errorCode) && !buffer.isEmpty();
+}
+
+UBool
+Normalizer::previousNormalize() {
+    clearBuffer();
+    nextIndex=currentIndex;
+    text->setIndex(currentIndex);
+    if(!text->hasPrevious()) {
+        return FALSE;
+    }
+    UnicodeString segment;
+    while(text->hasPrevious()) {
+        UChar32 c=text->previous32();
+        segment.insert(0, c);
+        if(fNorm2->hasBoundaryBefore(c)) {
+            break;
+        }
+    }
+    currentIndex=text->getIndex();
+    UErrorCode errorCode=U_ZERO_ERROR;
+    fNorm2->normalize(segment, buffer, errorCode);
+    bufferPos=buffer.length();
+    return U_SUCCESS(errorCode) && !buffer.isEmpty();
+}
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_NORMALIZATION */
diff --git a/icu/source/common/parsepos.cpp b/icu/source/common/parsepos.cpp
new file mode 100644
index 0000000..26f8820
--- /dev/null
+++ b/icu/source/common/parsepos.cpp
@@ -0,0 +1,21 @@
+/*
+**********************************************************************
+*   Copyright (C) 2003-2003, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*/
+
+#include "unicode/parsepos.h"
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ParsePosition)
+
+ParsePosition::~ParsePosition() {}
+
+ParsePosition *
+ParsePosition::clone() const {
+    return new ParsePosition(*this);
+}
+
+U_NAMESPACE_END
diff --git a/icu/source/common/propname.cpp b/icu/source/common/propname.cpp
new file mode 100644
index 0000000..1721f83
--- /dev/null
+++ b/icu/source/common/propname.cpp
@@ -0,0 +1,752 @@
+/*
+**********************************************************************
+* Copyright (c) 2002-2009, International Business Machines
+* Corporation and others.  All Rights Reserved.
+**********************************************************************
+* Author: Alan Liu
+* Created: October 30 2002
+* Since: ICU 2.4
+**********************************************************************
+*/
+#include "propname.h"
+#include "unicode/uchar.h"
+#include "unicode/udata.h"
+#include "umutex.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "ucln_cmn.h"
+#include "uarrsort.h"
+
+U_CDECL_BEGIN
+
+/**
+ * Get the next non-ignorable ASCII character from a property name
+ * and lowercases it.
+ * @return ((advance count for the name)<<8)|character
+ */
+static inline int32_t
+getASCIIPropertyNameChar(const char *name) {
+    int32_t i;
+    char c;
+
+    /* Ignore delimiters '-', '_', and ASCII White_Space */
+    for(i=0;
+        (c=name[i++])==0x2d || c==0x5f ||
+        c==0x20 || (0x09<=c && c<=0x0d);
+    ) {}
+
+    if(c!=0) {
+        return (i<<8)|(uint8_t)uprv_asciitolower((char)c);
+    } else {
+        return i<<8;
+    }
+}
+
+/**
+ * Get the next non-ignorable EBCDIC character from a property name
+ * and lowercases it.
+ * @return ((advance count for the name)<<8)|character
+ */
+static inline int32_t
+getEBCDICPropertyNameChar(const char *name) {
+    int32_t i;
+    char c;
+
+    /* Ignore delimiters '-', '_', and EBCDIC White_Space */
+    for(i=0;
+        (c=name[i++])==0x60 || c==0x6d ||
+        c==0x40 || c==0x05 || c==0x15 || c==0x25 || c==0x0b || c==0x0c || c==0x0d;
+    ) {}
+
+    if(c!=0) {
+        return (i<<8)|(uint8_t)uprv_ebcdictolower((char)c);
+    } else {
+        return i<<8;
+    }
+}
+
+/**
+ * Unicode property names and property value names are compared "loosely".
+ *
+ * UCD.html 4.0.1 says:
+ *   For all property names, property value names, and for property values for
+ *   Enumerated, Binary, or Catalog properties, use the following
+ *   loose matching rule:
+ *
+ *   LM3. Ignore case, whitespace, underscore ('_'), and hyphens.
+ *
+ * This function does just that, for (char *) name strings.
+ * It is almost identical to ucnv_compareNames() but also ignores
+ * C0 White_Space characters (U+0009..U+000d, and U+0085 on EBCDIC).
+ *
+ * @internal
+ */
+
+U_CAPI int32_t U_EXPORT2
+uprv_compareASCIIPropertyNames(const char *name1, const char *name2) {
+    int32_t rc, r1, r2;
+
+    for(;;) {
+        r1=getASCIIPropertyNameChar(name1);
+        r2=getASCIIPropertyNameChar(name2);
+
+        /* If we reach the ends of both strings then they match */
+        if(((r1|r2)&0xff)==0) {
+            return 0;
+        }
+        
+        /* Compare the lowercased characters */
+        if(r1!=r2) {
+            rc=(r1&0xff)-(r2&0xff);
+            if(rc!=0) {
+                return rc;
+            }
+        }
+
+        name1+=r1>>8;
+        name2+=r2>>8;
+    }
+}
+
+U_CAPI int32_t U_EXPORT2
+uprv_compareEBCDICPropertyNames(const char *name1, const char *name2) {
+    int32_t rc, r1, r2;
+
+    for(;;) {
+        r1=getEBCDICPropertyNameChar(name1);
+        r2=getEBCDICPropertyNameChar(name2);
+
+        /* If we reach the ends of both strings then they match */
+        if(((r1|r2)&0xff)==0) {
+            return 0;
+        }
+        
+        /* Compare the lowercased characters */
+        if(r1!=r2) {
+            rc=(r1&0xff)-(r2&0xff);
+            if(rc!=0) {
+                return rc;
+            }
+        }
+
+        name1+=r1>>8;
+        name2+=r2>>8;
+    }
+}
+
+U_CDECL_END
+
+U_NAMESPACE_BEGIN
+
+//----------------------------------------------------------------------
+// PropertyAliases implementation
+
+const char*
+PropertyAliases::chooseNameInGroup(Offset offset,
+                                   UPropertyNameChoice choice) const {
+    int32_t c = choice;
+    if (!offset || c < 0) {
+        return NULL;
+    }
+    const Offset* p = (const Offset*) getPointer(offset);
+    while (c-- > 0) {
+        if (*p++ < 0) return NULL;
+    }
+    Offset a = *p;
+    if (a < 0) a = -a;
+    return (const char*) getPointerNull(a);
+}
+
+const ValueMap*
+PropertyAliases::getValueMap(EnumValue prop) const {
+    NonContiguousEnumToOffset* e2o = (NonContiguousEnumToOffset*) getPointer(enumToValue_offset);
+    Offset a = e2o->getOffset(prop);
+    return (const ValueMap*) (a ? getPointerNull(a) : NULL);
+}
+
+inline const char*
+PropertyAliases::getPropertyName(EnumValue prop,
+                                 UPropertyNameChoice choice) const {
+    NonContiguousEnumToOffset* e2n = (NonContiguousEnumToOffset*) getPointer(enumToName_offset);
+    return chooseNameInGroup(e2n->getOffset(prop), choice);
+}
+
+inline EnumValue
+PropertyAliases::getPropertyEnum(const char* alias) const {
+    NameToEnum* n2e = (NameToEnum*) getPointer(nameToEnum_offset);
+    return n2e->getEnum(alias, *this);
+}
+
+inline const char*
+PropertyAliases::getPropertyValueName(EnumValue prop,
+                                      EnumValue value,
+                                      UPropertyNameChoice choice) const {
+    const ValueMap* vm = getValueMap(prop);
+    if (!vm) return NULL;
+    Offset a;
+    if (vm->enumToName_offset) {
+        a = ((EnumToOffset*) getPointer(vm->enumToName_offset))->
+            getOffset(value);
+    } else {
+        a = ((NonContiguousEnumToOffset*) getPointer(vm->ncEnumToName_offset))->
+            getOffset(value);
+    }
+    return chooseNameInGroup(a, choice);
+}
+
+inline EnumValue
+PropertyAliases::getPropertyValueEnum(EnumValue prop,
+                                      const char* alias) const {
+    const ValueMap* vm = getValueMap(prop);
+    if (!vm) return UCHAR_INVALID_CODE;
+    NameToEnum* n2e = (NameToEnum*) getPointer(vm->nameToEnum_offset);
+    return n2e->getEnum(alias, *this);
+}
+
+U_NAMESPACE_END
+U_NAMESPACE_USE
+
+//----------------------------------------------------------------------
+// UDataMemory structures
+
+static const PropertyAliases* PNAME = NULL;
+static UDataMemory* UDATA = NULL;
+
+//----------------------------------------------------------------------
+// UDataMemory loading/unloading
+
+/**
+ * udata callback to verify the zone data.
+ */
+U_CDECL_BEGIN
+static UBool U_CALLCONV
+isPNameAcceptable(void* /*context*/,
+             const char* /*type*/, const char* /*name*/,
+             const UDataInfo* info) {
+    return
+        info->size >= sizeof(UDataInfo) &&
+        info->isBigEndian == U_IS_BIG_ENDIAN &&
+        info->charsetFamily == U_CHARSET_FAMILY &&
+        info->dataFormat[0] == PNAME_SIG_0 &&
+        info->dataFormat[1] == PNAME_SIG_1 &&
+        info->dataFormat[2] == PNAME_SIG_2 &&
+        info->dataFormat[3] == PNAME_SIG_3 &&
+        info->formatVersion[0] == PNAME_FORMAT_VERSION;
+}
+
+static UBool U_CALLCONV pname_cleanup(void) {
+    if (UDATA) {
+        udata_close(UDATA);
+        UDATA = NULL;
+    }
+    PNAME = NULL;
+    return TRUE;
+}
+U_CDECL_END
+
+/**
+ * Load the property names data.  Caller should check that data is
+ * not loaded BEFORE calling this function.  Returns TRUE if the load
+ * succeeds.
+ */
+static UBool _load() {
+    UErrorCode ec = U_ZERO_ERROR;
+    UDataMemory* data =
+        udata_openChoice(0, PNAME_DATA_TYPE, PNAME_DATA_NAME,
+                         isPNameAcceptable, 0, &ec);
+    if (U_SUCCESS(ec)) {
+        umtx_lock(NULL);
+        if (UDATA == NULL) {
+            UDATA = data;
+            PNAME = (const PropertyAliases*) udata_getMemory(UDATA);
+            ucln_common_registerCleanup(UCLN_COMMON_PNAME, pname_cleanup);
+            data = NULL;
+        }
+        umtx_unlock(NULL);
+    }
+    if (data) {
+        udata_close(data);
+    }
+    return PNAME!=NULL;
+}
+
+/**
+ * Inline function that expands to code that does a lazy load of the
+ * property names data.  If the data is already loaded, avoids an
+ * unnecessary function call.  If the data is not loaded, call _load()
+ * to load it, and return TRUE if the load succeeds.
+ */
+static inline UBool load() {
+    UBool f;
+    UMTX_CHECK(NULL, (PNAME!=NULL), f);
+    return f || _load();
+}
+
+//----------------------------------------------------------------------
+// Public API implementation
+
+// The C API is just a thin wrapper.  Each function obtains a pointer
+// to the singleton PropertyAliases, and calls the appropriate method
+// on it.  If it cannot obtain a pointer, because valid data is not
+// available, then it returns NULL or UCHAR_INVALID_CODE.
+
+U_CAPI const char* U_EXPORT2
+u_getPropertyName(UProperty property,
+                  UPropertyNameChoice nameChoice) {
+    return load() ? PNAME->getPropertyName(property, nameChoice)
+                  : NULL;
+}
+
+U_CAPI UProperty U_EXPORT2
+u_getPropertyEnum(const char* alias) {
+    UProperty p = load() ? (UProperty) PNAME->getPropertyEnum(alias)
+                         : UCHAR_INVALID_CODE;
+    return p;
+}
+
+U_CAPI const char* U_EXPORT2
+u_getPropertyValueName(UProperty property,
+                       int32_t value,
+                       UPropertyNameChoice nameChoice) {
+    return load() ? PNAME->getPropertyValueName(property, value, nameChoice)
+                  : NULL;
+}
+
+U_CAPI int32_t U_EXPORT2
+u_getPropertyValueEnum(UProperty property,
+                       const char* alias) {
+    return load() ? PNAME->getPropertyValueEnum(property, alias)
+                  : (int32_t)UCHAR_INVALID_CODE;
+}
+
+/* data swapping ------------------------------------------------------------ */
+
+/*
+ * Sub-structure-swappers use the temp array (which is as large as the
+ * actual data) for intermediate storage,
+ * as well as to indicate if a particular structure has been swapped already.
+ * The temp array is initially reset to all 0.
+ * pos is the byte offset of the sub-structure in the inBytes/outBytes/temp arrays.
+ */
+
+int32_t
+EnumToOffset::swap(const UDataSwapper *ds,
+                   const uint8_t *inBytes, int32_t length, uint8_t *outBytes,
+                   uint8_t *temp, int32_t pos,
+                   UErrorCode *pErrorCode) {
+    const EnumToOffset *inMap;
+    EnumToOffset *outMap, *tempMap;
+    int32_t size;
+
+    tempMap=(EnumToOffset *)(temp+pos);
+    if(tempMap->enumStart!=0 || tempMap->enumLimit!=0) {
+        /* this map was swapped already */
+        size=tempMap->getSize();
+        return size;
+    }
+
+    inMap=(const EnumToOffset *)(inBytes+pos);
+    outMap=(EnumToOffset *)(outBytes+pos);
+
+    tempMap->enumStart=udata_readInt32(ds, inMap->enumStart);
+    tempMap->enumLimit=udata_readInt32(ds, inMap->enumLimit);
+    size=tempMap->getSize();
+
+    if(length>=0) {
+        if(length<(pos+size)) {
+            if(length<(int32_t)sizeof(PropertyAliases)) {
+                udata_printError(ds, "upname_swap(EnumToOffset): too few bytes (%d after header)\n"
+                                     "    for pnames.icu EnumToOffset{%d..%d} at %d\n",
+                                 length, tempMap->enumStart, tempMap->enumLimit, pos);
+                *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+                return 0;
+            }
+        }
+
+        /* swap enumStart and enumLimit */
+        ds->swapArray32(ds, inMap, 2*sizeof(EnumValue), outMap, pErrorCode);
+
+        /* swap _offsetArray[] */
+        ds->swapArray16(ds, inMap->getOffsetArray(), (tempMap->enumLimit-tempMap->enumStart)*sizeof(Offset),
+                           outMap->getOffsetArray(), pErrorCode);
+    }
+
+    return size;
+}
+
+int32_t
+NonContiguousEnumToOffset::swap(const UDataSwapper *ds,
+                   const uint8_t *inBytes, int32_t length, uint8_t *outBytes,
+                   uint8_t *temp, int32_t pos,
+                   UErrorCode *pErrorCode) {
+    const NonContiguousEnumToOffset *inMap;
+    NonContiguousEnumToOffset *outMap, *tempMap;
+    int32_t size;
+
+    tempMap=(NonContiguousEnumToOffset *)(temp+pos);
+    if(tempMap->count!=0) {
+        /* this map was swapped already */
+        size=tempMap->getSize();
+        return size;
+    }
+
+    inMap=(const NonContiguousEnumToOffset *)(inBytes+pos);
+    outMap=(NonContiguousEnumToOffset *)(outBytes+pos);
+
+    tempMap->count=udata_readInt32(ds, inMap->count);
+    size=tempMap->getSize();
+
+    if(length>=0) {
+        if(length<(pos+size)) {
+            if(length<(int32_t)sizeof(PropertyAliases)) {
+                udata_printError(ds, "upname_swap(NonContiguousEnumToOffset): too few bytes (%d after header)\n"
+                                     "    for pnames.icu NonContiguousEnumToOffset[%d] at %d\n",
+                                 length, tempMap->count, pos);
+                *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+                return 0;
+            }
+        }
+
+        /* swap count and _enumArray[] */
+        length=(1+tempMap->count)*sizeof(EnumValue);
+        ds->swapArray32(ds, inMap, length,
+                           outMap, pErrorCode);
+
+        /* swap _offsetArray[] */
+        pos+=length;
+        ds->swapArray16(ds, inBytes+pos, tempMap->count*sizeof(Offset),
+                           outBytes+pos, pErrorCode);
+    }
+
+    return size;
+}
+
+struct NameAndIndex {
+    Offset name, index;
+};
+
+U_CDECL_BEGIN
+typedef int32_t U_CALLCONV PropNameCompareFn(const char *name1, const char *name2);
+
+struct CompareContext {
+    const char *chars;
+    PropNameCompareFn *propCompare;
+};
+
+static int32_t U_CALLCONV
+upname_compareRows(const void *context, const void *left, const void *right) {
+    CompareContext *cmp=(CompareContext *)context;
+    return cmp->propCompare(cmp->chars+((const NameAndIndex *)left)->name,
+                            cmp->chars+((const NameAndIndex *)right)->name);
+}
+U_CDECL_END
+
+int32_t
+NameToEnum::swap(const UDataSwapper *ds,
+                   const uint8_t *inBytes, int32_t length, uint8_t *outBytes,
+                   uint8_t *temp, int32_t pos,
+                   UErrorCode *pErrorCode) {
+    const NameToEnum *inMap;
+    NameToEnum *outMap, *tempMap;
+
+    const EnumValue *inEnumArray;
+    EnumValue *outEnumArray;
+
+    const Offset *inNameArray;
+    Offset *outNameArray;
+
+    NameAndIndex *sortArray;
+    CompareContext cmp;
+
+    int32_t i, size, oldIndex;
+
+    tempMap=(NameToEnum *)(temp+pos);
+    if(tempMap->count!=0) {
+        /* this map was swapped already */
+        size=tempMap->getSize();
+        return size;
+    }
+
+    inMap=(const NameToEnum *)(inBytes+pos);
+    outMap=(NameToEnum *)(outBytes+pos);
+
+    tempMap->count=udata_readInt32(ds, inMap->count);
+    size=tempMap->getSize();
+
+    if(length>=0) {
+        if(length<(pos+size)) {
+            if(length<(int32_t)sizeof(PropertyAliases)) {
+                udata_printError(ds, "upname_swap(NameToEnum): too few bytes (%d after header)\n"
+                                     "    for pnames.icu NameToEnum[%d] at %d\n",
+                                 length, tempMap->count, pos);
+                *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+                return 0;
+            }
+        }
+
+        /* swap count */
+        ds->swapArray32(ds, inMap, 4, outMap, pErrorCode);
+
+        inEnumArray=inMap->getEnumArray();
+        outEnumArray=outMap->getEnumArray();
+
+        inNameArray=(const Offset *)(inEnumArray+tempMap->count);
+        outNameArray=(Offset *)(outEnumArray+tempMap->count);
+
+        if(ds->inCharset==ds->outCharset) {
+            /* no need to sort, just swap the enum/name arrays */
+            ds->swapArray32(ds, inEnumArray, tempMap->count*4, outEnumArray, pErrorCode);
+            ds->swapArray16(ds, inNameArray, tempMap->count*2, outNameArray, pErrorCode);
+            return size;
+        }
+
+        /*
+         * The name and enum arrays are sorted by names and must be resorted
+         * if inCharset!=outCharset.
+         * We use the corresponding part of the temp array to sort an array
+         * of pairs of name offsets and sorting indexes.
+         * Then the sorting indexes are used to permutate-swap the name and enum arrays.
+         *
+         * The outBytes must already contain the swapped strings.
+         */
+        sortArray=(NameAndIndex *)tempMap->getEnumArray();
+        for(i=0; i<tempMap->count; ++i) {
+            sortArray[i].name=udata_readInt16(ds, inNameArray[i]);
+            sortArray[i].index=(Offset)i;
+        }
+
+        /*
+         * use a stable sort to avoid shuffling of equal strings,
+         * which makes testing harder
+         */
+        cmp.chars=(const char *)outBytes;
+        if (ds->outCharset==U_ASCII_FAMILY) {
+            cmp.propCompare=uprv_compareASCIIPropertyNames;
+        }
+        else {
+            cmp.propCompare=uprv_compareEBCDICPropertyNames;
+        }
+        uprv_sortArray(sortArray, tempMap->count, sizeof(NameAndIndex),
+                       upname_compareRows, &cmp,
+                       TRUE, pErrorCode);
+        if(U_FAILURE(*pErrorCode)) {
+            udata_printError(ds, "upname_swap(NameToEnum).uprv_sortArray(%d items) failed\n",
+                             tempMap->count);
+            return 0;
+        }
+
+        /* copy/swap/permutate _enumArray[] and _nameArray[] */
+        if(inEnumArray!=outEnumArray) {
+            for(i=0; i<tempMap->count; ++i) {
+                oldIndex=sortArray[i].index;
+                ds->swapArray32(ds, inEnumArray+oldIndex, 4, outEnumArray+i, pErrorCode);
+                ds->swapArray16(ds, inNameArray+oldIndex, 2, outNameArray+i, pErrorCode);
+            }
+        } else {
+            /*
+             * in-place swapping: need to permutate into a temporary array
+             * and then copy back to not destroy the data
+             */
+            EnumValue *tempEnumArray;
+            Offset *oldIndexes;
+
+            /* write name offsets directly from sortArray */
+            for(i=0; i<tempMap->count; ++i) {
+                ds->writeUInt16((uint16_t *)outNameArray+i, (uint16_t)sortArray[i].name);
+            }
+
+            /*
+             * compress the oldIndexes into a separate array to make space for tempEnumArray
+             * the tempMap _nameArray becomes oldIndexes[], getting the index
+             *   values from the 2D sortArray[],
+             * while sortArray=tempMap _enumArray[] becomes tempEnumArray[]
+             * this saves us allocating more memory
+             *
+             * it works because sizeof(NameAndIndex)<=sizeof(EnumValue)
+             * and because the nameArray[] can be used for oldIndexes[]
+             */
+            tempEnumArray=(EnumValue *)sortArray;
+            oldIndexes=(Offset *)(sortArray+tempMap->count);
+
+            /* copy sortArray[].index values into oldIndexes[] */
+            for(i=0; i<tempMap->count; ++i) {
+                oldIndexes[i]=sortArray[i].index;
+            }
+
+            /* permutate inEnumArray[] into tempEnumArray[] */
+            for(i=0; i<tempMap->count; ++i) {
+                ds->swapArray32(ds, inEnumArray+oldIndexes[i], 4, tempEnumArray+i, pErrorCode);
+            }
+
+            /* copy tempEnumArray[] to outEnumArray[] */
+            uprv_memcpy(outEnumArray, tempEnumArray, tempMap->count*4);
+        }
+    }
+
+    return size;
+}
+
+int32_t
+PropertyAliases::swap(const UDataSwapper *ds,
+                      const uint8_t *inBytes, int32_t length, uint8_t *outBytes,
+                      UErrorCode *pErrorCode) {
+    const PropertyAliases *inAliases;
+    PropertyAliases *outAliases;
+    PropertyAliases aliases;
+
+    const ValueMap *inValueMaps;
+    ValueMap *outValueMaps;
+    ValueMap valueMap;
+
+    int32_t i;
+
+    inAliases=(const PropertyAliases *)inBytes;
+    outAliases=(PropertyAliases *)outBytes;
+
+    /* read the input PropertyAliases - all 16-bit values */
+    for(i=0; i<(int32_t)sizeof(PropertyAliases)/2; ++i) {
+        ((uint16_t *)&aliases)[i]=ds->readUInt16(((const uint16_t *)inBytes)[i]);
+    }
+
+    if(length>=0) {
+        if(length<aliases.total_size) {
+            udata_printError(ds, "upname_swap(): too few bytes (%d after header) for all of pnames.icu\n",
+                             length);
+            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+            return 0;
+        }
+
+        /* copy the data for inaccessible bytes */
+        if(inBytes!=outBytes) {
+            uprv_memcpy(outBytes, inBytes, aliases.total_size);
+        }
+
+        /* swap the PropertyAliases class fields */
+        ds->swapArray16(ds, inAliases, sizeof(PropertyAliases), outAliases, pErrorCode);
+
+        /* swap the name groups */
+        ds->swapArray16(ds, inBytes+aliases.nameGroupPool_offset,
+                                aliases.stringPool_offset-aliases.nameGroupPool_offset,
+                           outBytes+aliases.nameGroupPool_offset, pErrorCode);
+
+        /* swap the strings */
+        udata_swapInvStringBlock(ds, inBytes+aliases.stringPool_offset,
+                                        aliases.total_size-aliases.stringPool_offset,
+                                    outBytes+aliases.stringPool_offset, pErrorCode);
+
+        /*
+         * alloc uint8_t temp[total_size] and reset it
+         * swap each top-level struct, put at least the count fields into temp
+         *   use subclass-specific swap() functions
+         * enumerate value maps, for each
+         *   if temp does not have count!=0 yet
+         *     read count, put it into temp
+         *     swap the array(s)
+         *     resort strings in name->enum maps
+         * swap value maps
+         */
+        LocalMemory<uint8_t> temp;
+        if(temp.allocateInsteadAndReset(aliases.total_size)==NULL) {
+            udata_printError(ds, "upname_swap(): unable to allocate temp memory (%d bytes)\n",
+                             aliases.total_size);
+            *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+            return 0;
+        }
+
+        /* swap properties->name groups map */
+        NonContiguousEnumToOffset::swap(ds, inBytes, length, outBytes,
+                                        temp.getAlias(), aliases.enumToName_offset, pErrorCode);
+
+        /* swap name->properties map */
+        NameToEnum::swap(ds, inBytes, length, outBytes,
+                         temp.getAlias(), aliases.nameToEnum_offset, pErrorCode);
+
+        /* swap properties->value maps map */
+        NonContiguousEnumToOffset::swap(ds, inBytes, length, outBytes,
+                                        temp.getAlias(), aliases.enumToValue_offset, pErrorCode);
+
+        /* enumerate all ValueMaps and swap them */
+        inValueMaps=(const ValueMap *)(inBytes+aliases.valueMap_offset);
+        outValueMaps=(ValueMap *)(outBytes+aliases.valueMap_offset);
+
+        for(i=0; i<aliases.valueMap_count; ++i) {
+            valueMap.enumToName_offset=udata_readInt16(ds, inValueMaps[i].enumToName_offset);
+            valueMap.ncEnumToName_offset=udata_readInt16(ds, inValueMaps[i].ncEnumToName_offset);
+            valueMap.nameToEnum_offset=udata_readInt16(ds, inValueMaps[i].nameToEnum_offset);
+
+            if(valueMap.enumToName_offset!=0) {
+                EnumToOffset::swap(ds, inBytes, length, outBytes,
+                                   temp.getAlias(), valueMap.enumToName_offset,
+                                   pErrorCode);
+            } else if(valueMap.ncEnumToName_offset!=0) {
+                NonContiguousEnumToOffset::swap(ds, inBytes, length, outBytes,
+                                                temp.getAlias(), valueMap.ncEnumToName_offset,
+                                                pErrorCode);
+            }
+            if(valueMap.nameToEnum_offset!=0) {
+                NameToEnum::swap(ds, inBytes, length, outBytes,
+                                 temp.getAlias(), valueMap.nameToEnum_offset,
+                                 pErrorCode);
+            }
+        }
+
+        /* swap the ValueMaps array itself */
+        ds->swapArray16(ds, inValueMaps, aliases.valueMap_count*sizeof(ValueMap),
+                           outValueMaps, pErrorCode);
+
+        /* name groups and strings were swapped above */
+    }
+
+    return aliases.total_size;
+}
+
+U_CAPI int32_t U_EXPORT2
+upname_swap(const UDataSwapper *ds,
+            const void *inData, int32_t length, void *outData,
+            UErrorCode *pErrorCode) {
+    const UDataInfo *pInfo;
+    int32_t headerSize;
+
+    const uint8_t *inBytes;
+    uint8_t *outBytes;
+
+    /* udata_swapDataHeader checks the arguments */
+    headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode);
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    /* check data format and format version */
+    pInfo=(const UDataInfo *)((const char *)inData+4);
+    if(!(
+        pInfo->dataFormat[0]==0x70 &&   /* dataFormat="pnam" */
+        pInfo->dataFormat[1]==0x6e &&
+        pInfo->dataFormat[2]==0x61 &&
+        pInfo->dataFormat[3]==0x6d &&
+        pInfo->formatVersion[0]==1
+    )) {
+        udata_printError(ds, "upname_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as pnames.icu\n",
+                         pInfo->dataFormat[0], pInfo->dataFormat[1],
+                         pInfo->dataFormat[2], pInfo->dataFormat[3],
+                         pInfo->formatVersion[0]);
+        *pErrorCode=U_UNSUPPORTED_ERROR;
+        return 0;
+    }
+
+    inBytes=(const uint8_t *)inData+headerSize;
+    outBytes=(uint8_t *)outData+headerSize;
+
+    if(length>=0) {
+        length-=headerSize;
+        if(length<(int32_t)sizeof(PropertyAliases)) {
+            udata_printError(ds, "upname_swap(): too few bytes (%d after header) for pnames.icu\n",
+                             length);
+            *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+            return 0;
+        }
+    }
+
+    return headerSize+PropertyAliases::swap(ds, inBytes, length, outBytes, pErrorCode);
+}
+
+//eof
diff --git a/icu/source/common/propname.h b/icu/source/common/propname.h
new file mode 100644
index 0000000..a3a7718
--- /dev/null
+++ b/icu/source/common/propname.h
@@ -0,0 +1,515 @@
+/*
+**********************************************************************
+* Copyright (c) 2002-2004, International Business Machines
+* Corporation and others.  All Rights Reserved.
+**********************************************************************
+* Author: Alan Liu
+* Created: October 30 2002
+* Since: ICU 2.4
+**********************************************************************
+*/
+#ifndef PROPNAME_H
+#define PROPNAME_H
+
+#include "unicode/utypes.h"
+#include "unicode/uchar.h"
+#include "udataswp.h"
+#include "uprops.h"
+
+/*
+ * This header defines the in-memory layout of the property names data
+ * structure representing the UCD data files PropertyAliases.txt and
+ * PropertyValueAliases.txt.  It is used by:
+ *   propname.cpp - reads data
+ *   genpname     - creates data
+ */
+
+/* low-level char * property name comparison -------------------------------- */
+
+U_CDECL_BEGIN
+
+/**
+ * \var uprv_comparePropertyNames
+ * Unicode property names and property value names are compared "loosely".
+ *
+ * UCD.html 4.0.1 says:
+ *   For all property names, property value names, and for property values for
+ *   Enumerated, Binary, or Catalog properties, use the following
+ *   loose matching rule:
+ *
+ *   LM3. Ignore case, whitespace, underscore ('_'), and hyphens.
+ *
+ * This function does just that, for (char *) name strings.
+ * It is almost identical to ucnv_compareNames() but also ignores
+ * C0 White_Space characters (U+0009..U+000d, and U+0085 on EBCDIC).
+ *
+ * @internal
+ */
+
+U_CAPI int32_t U_EXPORT2
+uprv_compareASCIIPropertyNames(const char *name1, const char *name2);
+
+U_CAPI int32_t U_EXPORT2
+uprv_compareEBCDICPropertyNames(const char *name1, const char *name2);
+
+#if U_CHARSET_FAMILY==U_ASCII_FAMILY
+#   define uprv_comparePropertyNames uprv_compareASCIIPropertyNames
+#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
+#   define uprv_comparePropertyNames uprv_compareEBCDICPropertyNames
+#else
+#   error U_CHARSET_FAMILY is not valid
+#endif
+
+U_CDECL_END
+
+/* UDataMemory structure and signatures ------------------------------------- */
+
+#define PNAME_DATA_NAME "pnames"
+#define PNAME_DATA_TYPE "icu"
+
+/* Fields in UDataInfo: */
+
+/* PNAME_SIG[] is encoded as numeric literals for compatibility with the HP compiler */
+#define PNAME_SIG_0 ((uint8_t)0x70) /* p */
+#define PNAME_SIG_1 ((uint8_t)0x6E) /* n */
+#define PNAME_SIG_2 ((uint8_t)0x61) /* a */
+#define PNAME_SIG_3 ((uint8_t)0x6D) /* m */
+
+#define PNAME_FORMAT_VERSION ((int8_t)1) /* formatVersion[0] */
+
+/**
+ * Swap pnames.icu. See udataswp.h.
+ * @internal
+ */
+U_CAPI int32_t U_EXPORT2
+upname_swap(const UDataSwapper *ds,
+            const void *inData, int32_t length, void *outData,
+            UErrorCode *pErrorCode);
+
+
+#ifdef XP_CPLUSPLUS
+
+class Builder;
+
+U_NAMESPACE_BEGIN
+
+/**
+ * An offset from the start of the pnames data to a contained entity.
+ * This must be a signed value, since negative offsets are used as an
+ * end-of-list marker.  Offsets to actual objects are non-zero.  A
+ * zero offset indicates an absent entry; this corresponds to aliases
+ * marked "n/a" in the original Unicode data files.
+ */
+typedef int16_t Offset; /*  must be signed */
+
+#define MAX_OFFSET 0x7FFF
+
+/**
+ * A generic value for a property or property value.  Typically an
+ * enum from uchar.h, but sometimes a non-enum value.  It must be
+ * large enough to accomodate the largest enum value, which as of this
+ * writing is the largest general category mask.  Need not be signed
+ * but may be.  Typically it doesn't matter, since the caller will
+ * cast it to the proper type before use.  Takes the special value
+ * UCHAR_INVALID_CODE for invalid input.
+ */
+typedef int32_t EnumValue;
+
+/* ---------------------------------------------------------------------- */
+/*  ValueMap */
+
+/**
+ * For any top-level property that has named values (binary and
+ * enumerated properties), there is a ValueMap object.  This object
+ * maps from enum values to two other maps.  One goes from value enums
+ * to value names.  The other goes from value names to value enums.
+ * 
+ * The value enum values may be contiguous or disjoint.  If they are
+ * contiguous then the enumToName_offset is nonzero, and the
+ * ncEnumToName_offset is zero.  Vice versa if the value enums are
+ * disjoint.
+ *
+ * There are n of these objects, where n is the number of binary
+ * properties + the number of enumerated properties.
+ */
+struct ValueMap {
+
+    /*  -- begin pnames data -- */
+    /*  Enum=>name EnumToOffset / NonContiguousEnumToOffset objects. */
+    /*  Exactly one of these will be nonzero. */
+    Offset enumToName_offset;
+    Offset ncEnumToName_offset;
+
+    Offset nameToEnum_offset; /*  Name=>enum data */
+    /*  -- end pnames data -- */
+};
+
+/* ---------------------------------------------------------------------- */
+/*  PropertyAliases class */
+
+/**
+ * A class encapsulating access to the memory-mapped data representing
+ * property aliases and property value aliases (pnames).  The class
+ * MUST have no v-table and declares certain methods inline -- small
+ * methods and methods that are called from only one point.
+ *
+ * The data members in this class correspond to the in-memory layout
+ * of the header of the pnames data.
+ */
+class PropertyAliases {
+
+    /*  -- begin pnames data -- */
+    /*  Enum=>name EnumToOffset object for binary and enumerated */
+    /*  properties */
+    Offset enumToName_offset;
+
+    /*  Name=>enum data for binary & enumerated properties */
+    Offset nameToEnum_offset;
+
+    /*  Enum=>offset EnumToOffset object mapping enumerated properties */
+    /*  to ValueMap objects */
+    Offset enumToValue_offset;
+
+    /*  The following are needed by external readers of this data. */
+    /*  We don't use them ourselves. */
+    int16_t total_size; /*  size in bytes excluding the udata header */
+    Offset valueMap_offset; /*  offset to start of array */
+    int16_t valueMap_count; /*  number of entries */
+    Offset nameGroupPool_offset; /*  offset to start of array */
+    int16_t nameGroupPool_count; /*  number of entries (not groups) */
+    Offset stringPool_offset; /*  offset to start of pool */
+    int16_t stringPool_count; /*  number of strings (not size in bytes) */
+
+    /*  -- end pnames data -- */
+
+    friend class ::Builder;
+
+    const ValueMap* getValueMap(EnumValue prop) const;
+
+    const char* chooseNameInGroup(Offset offset,
+                                  UPropertyNameChoice choice) const;
+
+ public:
+
+    inline const int8_t* getPointer(Offset o) const {
+        return ((const int8_t*) this) + o;
+    }
+
+    inline const int8_t* getPointerNull(Offset o) const {
+        return o ? getPointer(o) : NULL;
+    }
+
+    inline const char* getPropertyName(EnumValue prop,
+                                       UPropertyNameChoice choice) const;
+    
+    inline EnumValue getPropertyEnum(const char* alias) const;
+
+    inline const char* getPropertyValueName(EnumValue prop, EnumValue value,
+                                            UPropertyNameChoice choice) const;
+    
+    inline EnumValue getPropertyValueEnum(EnumValue prop,
+                                          const char* alias) const;
+
+    static int32_t
+    swap(const UDataSwapper *ds,
+         const uint8_t *inBytes, int32_t length, uint8_t *outBytes,
+         UErrorCode *pErrorCode);
+};
+
+/* ---------------------------------------------------------------------- */
+/*  EnumToOffset */
+
+/**
+ * A generic map from enum values to Offsets.  The enum values must be
+ * contiguous, from enumStart to enumLimit.  The Offset values may
+ * point to anything.
+ */
+class EnumToOffset {
+
+    /*  -- begin pnames data -- */
+    EnumValue enumStart;
+    EnumValue enumLimit;
+    Offset _offsetArray; /*  [array of enumLimit-enumStart] */
+    /*  -- end pnames data -- */
+
+    friend class ::Builder;
+
+    Offset* getOffsetArray() {
+        return &_offsetArray;
+    }
+
+    const Offset* getOffsetArray() const {
+        return &_offsetArray;
+    }
+
+    static int32_t getSize(int32_t n) {
+        return sizeof(EnumToOffset) + sizeof(Offset) * (n - 1);
+    }
+
+    int32_t getSize() {
+        return getSize(enumLimit - enumStart);
+    }
+
+ public:
+
+    Offset getOffset(EnumValue enumProbe) const {
+        if (enumProbe < enumStart ||
+            enumProbe >= enumLimit) {
+            return 0; /*  not found */
+        }
+        const Offset* p = getOffsetArray();
+        return p[enumProbe - enumStart];
+    }
+
+    static int32_t
+    swap(const UDataSwapper *ds,
+         const uint8_t *inBytes, int32_t length, uint8_t *outBytes,
+         uint8_t *temp, int32_t pos,
+         UErrorCode *pErrorCode);
+};
+
+/* ---------------------------------------------------------------------- */
+/*  NonContiguousEnumToOffset */
+
+/**
+ * A generic map from enum values to Offsets.  The enum values may be
+ * disjoint.  If they are contiguous, an EnumToOffset should be used
+ * instead.  The Offset values may point to anything.
+ */
+class NonContiguousEnumToOffset {
+
+    /*  -- begin pnames data -- */
+    int32_t count;
+    EnumValue _enumArray; /*  [array of count] */
+    /*  Offset _offsetArray; // [array of count] after enumValue[count-1] */
+    /*  -- end pnames data -- */
+
+    friend class ::Builder;
+
+    EnumValue* getEnumArray() {
+        return &_enumArray;
+    }
+
+    const EnumValue* getEnumArray() const {
+        return &_enumArray;
+    }
+    
+    Offset* getOffsetArray() {
+        return (Offset*) (getEnumArray() + count);
+    }
+
+    const Offset* getOffsetArray() const {
+        return (Offset*) (getEnumArray() + count);
+    }
+
+    static int32_t getSize(int32_t n) {
+        return sizeof(int32_t) + (sizeof(EnumValue) + sizeof(Offset)) * n;
+    }
+
+    int32_t getSize() {
+        return getSize(count);
+    }
+
+ public:
+
+    Offset getOffset(EnumValue enumProbe) const {
+        const EnumValue* e = getEnumArray();
+        const Offset* p = getOffsetArray();
+        /*  linear search; binary later if warranted */
+        /*  (binary is not faster for short lists) */
+        for (int32_t i=0; i<count; ++i) {
+            if (e[i] < enumProbe) continue;
+            if (e[i] > enumProbe) break;
+            return p[i];
+        }
+        return 0; /*  not found */
+    }
+
+    static int32_t
+    swap(const UDataSwapper *ds,
+         const uint8_t *inBytes, int32_t length, uint8_t *outBytes,
+         uint8_t *temp, int32_t pos,
+         UErrorCode *pErrorCode);
+};
+
+/* ---------------------------------------------------------------------- */
+/*  NameToEnum */
+
+/**
+ * A map from names to enum values.
+ */
+class NameToEnum {
+
+    /*  -- begin pnames data -- */
+    int32_t count;       /*  number of entries */
+    EnumValue _enumArray; /*  [array of count] EnumValues */
+    /*  Offset _nameArray; // [array of count] offsets to names */
+    /*  -- end pnames data -- */
+
+    friend class ::Builder;
+
+    EnumValue* getEnumArray() {
+        return &_enumArray;
+    }
+
+    const EnumValue* getEnumArray() const {
+        return &_enumArray;
+    }
+
+    Offset* getNameArray() {
+        return (Offset*) (getEnumArray() + count);
+    }
+
+    const Offset* getNameArray() const {
+        return (Offset*) (getEnumArray() + count);
+    }
+
+    static int32_t getSize(int32_t n) {
+        return sizeof(int32_t) + (sizeof(Offset) + sizeof(EnumValue)) * n;
+    }
+
+    int32_t getSize() {
+        return getSize(count);
+    }
+
+ public:
+  
+    EnumValue getEnum(const char* alias, const PropertyAliases& data) const {
+
+        const Offset* n = getNameArray();
+        const EnumValue* e = getEnumArray();
+
+        /*  linear search; binary later if warranted */
+        /*  (binary is not faster for short lists) */
+        for (int32_t i=0; i<count; ++i) {
+            const char* name = (const char*) data.getPointer(n[i]);
+            int32_t c = uprv_comparePropertyNames(alias, name);
+            if (c > 0) continue;
+            if (c < 0) break;
+            return e[i];
+        }
+        
+        return UCHAR_INVALID_CODE;
+    }
+
+    static int32_t
+    swap(const UDataSwapper *ds,
+         const uint8_t *inBytes, int32_t length, uint8_t *outBytes,
+         uint8_t *temp, int32_t pos,
+         UErrorCode *pErrorCode);
+};
+
+/*----------------------------------------------------------------------
+ * 
+ * In-memory layout.  THIS IS NOT A STANDALONE DOCUMENT.  It goes
+ * together with above C++ declarations and gives an overview.
+ *
+ * See above for definitions of Offset and EnumValue.  Also, refer to
+ * above class declarations for the "bottom line" on data layout.
+ *
+ * Sizes:
+ * '*_offset' is an Offset (see above)
+ * 'count' members are typically int32_t (see above declarations)
+ * 'enumArray' is an array of EnumValue (see above)
+ * 'offsetArray' is an array of Offset (see above)
+ * 'nameArray' is an array of Offset (see above)
+ * 'enum*' is an EnumValue (see above)
+ * '*Array [x n]' means that *Array has n elements
+ *
+ * References:
+ * Instead of pointers, this flat data structure contains offsets.
+ * All offsets are relative to the start of 'header'.  A notation
+ * is used to indicate what structure each offset points to:
+ * 'foo (>x)' the offset(s) in foo point to structure x
+ * 
+ * Structures:
+ * Each structure is assigned a number, except for the header,
+ * which is called 'header'.  The numbers are not contiguous
+ * for historical reasons.  Some structures have sub-parts
+ * that are denoted with a letter, e.g., "5a".
+ * 
+ * BEGIN LAYOUT
+ * ============
+ * header:
+ *  enumToName_offset (>0)
+ *  nameToEnum_offset (>2)
+ *  enumToValue_offset (>3)
+ *  (alignment padding build in to header)
+ *
+ * The header also contains the following, used by "external readers"
+ * like ICU4J and icuswap.
+ *
+ *  // The following are needed by external readers of this data.
+ *  // We don't use them ourselves.
+ *  int16_t total_size; // size in bytes excluding the udata header
+ *  Offset valueMap_offset; // offset to start of array
+ *  int16_t valueMap_count; // number of entries
+ *  Offset nameGroupPool_offset; // offset to start of array
+ *  int16_t nameGroupPool_count; // number of entries (not groups)
+ *  Offset stringPool_offset; // offset to start of pool
+ *  int16_t stringPool_count; // number of strings (not size in bytes)
+ *
+ * 0: # NonContiguousEnumToOffset obj for props => name groups
+ *  count
+ *  enumArray [x count]
+ *  offsetArray [x count] (>98)
+ * 
+ * => pad to next 4-byte boundary
+ * 
+ * (1: omitted -- no longer used)
+ * 
+ * 2: # NameToEnum obj for binary & enumerated props
+ *  count
+ *  enumArray [x count]
+ *  nameArray [x count] (>99)
+ * 
+ * => pad to next 4-byte boundary
+ * 
+ * 3: # NonContiguousEnumToOffset obj for enumerated props => ValueMaps
+ *  count
+ *  enumArray [x count]
+ *  offsetArray [x count] (>4)
+ * 
+ * => pad to next 4-byte boundary
+ * 
+ * 4: # ValueMap array [x one for each enumerated prop i]
+ *  enumToName_offset (>5a +2*i)   one of these two is NULL, one is not
+ *  ncEnumToName_offset (>5b +2*i)
+ *  nameToEnums_offset (>6 +2*i)
+ * 
+ * => pad to next 4-byte boundary
+ * 
+ * for each enumerated prop (either 5a or 5b):
+ * 
+ *   5a: # EnumToOffset for enumerated prop's values => name groups
+ *    enumStart
+ *    enumLimit
+ *    offsetArray [x enumLimit - enumStart] (>98) 
+ * 
+ *   => pad to next 4-byte boundary
+ * 
+ *   5b: # NonContiguousEnumToOffset for enumerated prop's values => name groups
+ *    count
+ *    enumArray [x count]
+ *    offsetArray [x count] (>98)
+ * 
+ *   => pad to next 4-byte boundary
+ * 
+ *   6: # NameToEnum for enumerated prop's values
+ *    count
+ *    enumArray [x count]
+ *    nameArray [x count] (>99)
+ * 
+ *   => pad to next 4-byte boundary
+ * 
+ * 98: # name group pool {NGP}
+ *  [array of Offset values] (>99)
+ * 
+ * 99: # string pool {SP}
+ *  [pool of nul-terminated char* strings]
+ */
+U_NAMESPACE_END
+
+#endif /* C++ */
+
+#endif
diff --git a/icu/source/common/propsvec.c b/icu/source/common/propsvec.c
new file mode 100644
index 0000000..41e8b9b
--- /dev/null
+++ b/icu/source/common/propsvec.c
@@ -0,0 +1,557 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2002-2009, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  propsvec.c
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2002feb22
+*   created by: Markus W. Scherer
+*
+*   Store bits (Unicode character properties) in bit set vectors.
+*/
+
+#include <stdlib.h>
+#include "unicode/utypes.h"
+#include "cmemory.h"
+#include "utrie.h"
+#include "utrie2.h"
+#include "uarrsort.h"
+#include "propsvec.h"
+
+struct UPropsVectors {
+    uint32_t *v;
+    int32_t columns;  /* number of columns, plus two for start & limit values */
+    int32_t maxRows;
+    int32_t rows;
+    int32_t prevRow;  /* search optimization: remember last row seen */
+    UBool isCompacted;
+};
+
+#define UPVEC_INITIAL_ROWS (1<<12)
+#define UPVEC_MEDIUM_ROWS ((int32_t)1<<16)
+#define UPVEC_MAX_ROWS (UPVEC_MAX_CP+1)
+
+U_CAPI UPropsVectors * U_EXPORT2
+upvec_open(int32_t columns, UErrorCode *pErrorCode) {
+    UPropsVectors *pv;
+    uint32_t *v, *row;
+    uint32_t cp;
+
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+    if(columns<1) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return NULL;
+    }
+    columns+=2; /* count range start and limit columns */
+
+    pv=(UPropsVectors *)uprv_malloc(sizeof(UPropsVectors));
+    v=(uint32_t *)uprv_malloc(UPVEC_INITIAL_ROWS*columns*4);
+    if(pv==NULL || v==NULL) {
+        uprv_free(pv);
+        uprv_free(v);
+        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
+    }
+    uprv_memset(pv, 0, sizeof(UPropsVectors));
+    pv->v=v;
+    pv->columns=columns;
+    pv->maxRows=UPVEC_INITIAL_ROWS;
+    pv->rows=2+(UPVEC_MAX_CP-UPVEC_FIRST_SPECIAL_CP);
+
+    /* set the all-Unicode row and the special-value rows */
+    row=pv->v;
+    uprv_memset(row, 0, pv->rows*columns*4);
+    row[0]=0;
+    row[1]=0x110000;
+    row+=columns;
+    for(cp=UPVEC_FIRST_SPECIAL_CP; cp<=UPVEC_MAX_CP; ++cp) {
+        row[0]=cp;
+        row[1]=cp+1;
+        row+=columns;
+    }
+    return pv;
+}
+
+U_CAPI void U_EXPORT2
+upvec_close(UPropsVectors *pv) {
+    if(pv!=NULL) {
+        uprv_free(pv->v);
+        uprv_free(pv);
+    }
+}
+
+static uint32_t *
+_findRow(UPropsVectors *pv, UChar32 rangeStart) {
+    uint32_t *row;
+    int32_t columns, i, start, limit, prevRow, rows;
+
+    columns=pv->columns;
+    rows=limit=pv->rows;
+    prevRow=pv->prevRow;
+
+    /* check the vicinity of the last-seen row (start searching with an unrolled loop) */
+    row=pv->v+prevRow*columns;
+    if(rangeStart>=(UChar32)row[0]) {
+        if(rangeStart<(UChar32)row[1]) {
+            /* same row as last seen */
+            return row;
+        } else if(rangeStart<(UChar32)(row+=columns)[1]) {
+            /* next row after the last one */
+            pv->prevRow=prevRow+1;
+            return row;
+        } else if(rangeStart<(UChar32)(row+=columns)[1]) {
+            /* second row after the last one */
+            pv->prevRow=prevRow+2;
+            return row;
+        } else if((rangeStart-(UChar32)row[1])<10) {
+            /* we are close, continue looping */
+            prevRow+=2;
+            do {
+                ++prevRow;
+                row+=columns;
+            } while(rangeStart>=(UChar32)row[1]);
+            pv->prevRow=prevRow;
+            return row;
+        }
+    } else if(rangeStart<(UChar32)pv->v[1]) {
+        /* the very first row */
+        pv->prevRow=0;
+        return pv->v;
+    }
+
+    /* do a binary search for the start of the range */
+    start=0;
+    while(start<limit-1) {
+        i=(start+limit)/2;
+        row=pv->v+i*columns;
+        if(rangeStart<(UChar32)row[0]) {
+            limit=i;
+        } else if(rangeStart<(UChar32)row[1]) {
+            pv->prevRow=i;
+            return row;
+        } else {
+            start=i;
+        }
+    }
+
+    /* must be found because all ranges together always cover all of Unicode */
+    pv->prevRow=start;
+    return pv->v+start*columns;
+}
+
+U_CAPI void U_EXPORT2
+upvec_setValue(UPropsVectors *pv,
+               UChar32 start, UChar32 end,
+               int32_t column,
+               uint32_t value, uint32_t mask,
+               UErrorCode *pErrorCode) {
+    uint32_t *firstRow, *lastRow;
+    int32_t columns;
+    UChar32 limit;
+    UBool splitFirstRow, splitLastRow;
+
+    /* argument checking */
+    if(U_FAILURE(*pErrorCode)) {
+        return;
+    }
+    if( pv==NULL ||
+        start<0 || start>end || end>UPVEC_MAX_CP ||
+        column<0 || column>=(pv->columns-2)
+    ) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    if(pv->isCompacted) {
+        *pErrorCode=U_NO_WRITE_PERMISSION;
+        return;
+    }
+    limit=end+1;
+
+    /* initialize */
+    columns=pv->columns;
+    column+=2; /* skip range start and limit columns */
+    value&=mask;
+
+    /* find the rows whose ranges overlap with the input range */
+
+    /* find the first and last rows, always successful */
+    firstRow=_findRow(pv, start);
+    lastRow=_findRow(pv, end);
+
+    /*
+     * Rows need to be split if they partially overlap with the
+     * input range (only possible for the first and last rows)
+     * and if their value differs from the input value.
+     */
+    splitFirstRow= (UBool)(start!=(UChar32)firstRow[0] && value!=(firstRow[column]&mask));
+    splitLastRow= (UBool)(limit!=(UChar32)lastRow[1] && value!=(lastRow[column]&mask));
+
+    /* split first/last rows if necessary */
+    if(splitFirstRow || splitLastRow) {
+        int32_t count, rows;
+
+        rows=pv->rows;
+        if((rows+splitFirstRow+splitLastRow)>pv->maxRows) {
+            uint32_t *newVectors;
+            int32_t newMaxRows;
+
+            if(pv->maxRows<UPVEC_MEDIUM_ROWS) {
+                newMaxRows=UPVEC_MEDIUM_ROWS;
+            } else if(pv->maxRows<UPVEC_MAX_ROWS) {
+                newMaxRows=UPVEC_MAX_ROWS;
+            } else {
+                /* Implementation bug, or UPVEC_MAX_ROWS too low. */
+                *pErrorCode=U_INTERNAL_PROGRAM_ERROR;
+                return;
+            }
+            newVectors=(uint32_t *)uprv_malloc(newMaxRows*columns*4);
+            if(newVectors==NULL) {
+                *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+                return;
+            }
+            uprv_memcpy(newVectors, pv->v, rows*columns*4);
+            firstRow=newVectors+(firstRow-pv->v);
+            lastRow=newVectors+(lastRow-pv->v);
+            uprv_free(pv->v);
+            pv->v=newVectors;
+            pv->maxRows=newMaxRows;
+        }
+
+        /* count the number of row cells to move after the last row, and move them */
+        count = (int32_t)((pv->v+rows*columns)-(lastRow+columns));
+        if(count>0) {
+            uprv_memmove(
+                lastRow+(1+splitFirstRow+splitLastRow)*columns,
+                lastRow+columns,
+                count*4);
+        }
+        pv->rows=rows+splitFirstRow+splitLastRow;
+
+        /* split the first row, and move the firstRow pointer to the second part */
+        if(splitFirstRow) {
+            /* copy all affected rows up one and move the lastRow pointer */
+            count = (int32_t)((lastRow-firstRow)+columns);
+            uprv_memmove(firstRow+columns, firstRow, count*4);
+            lastRow+=columns;
+
+            /* split the range and move the firstRow pointer */
+            firstRow[1]=firstRow[columns]=(uint32_t)start;
+            firstRow+=columns;
+        }
+
+        /* split the last row */
+        if(splitLastRow) {
+            /* copy the last row data */
+            uprv_memcpy(lastRow+columns, lastRow, columns*4);
+
+            /* split the range and move the firstRow pointer */
+            lastRow[1]=lastRow[columns]=(uint32_t)limit;
+        }
+    }
+
+    /* set the "row last seen" to the last row for the range */
+    pv->prevRow=(int32_t)((lastRow-(pv->v))/columns);
+
+    /* set the input value in all remaining rows */
+    firstRow+=column;
+    lastRow+=column;
+    mask=~mask;
+    for(;;) {
+        *firstRow=(*firstRow&mask)|value;
+        if(firstRow==lastRow) {
+            break;
+        }
+        firstRow+=columns;
+    }
+}
+
+U_CAPI uint32_t U_EXPORT2
+upvec_getValue(const UPropsVectors *pv, UChar32 c, int32_t column) {
+    uint32_t *row;
+    UPropsVectors *ncpv;
+
+    if(pv->isCompacted || c<0 || c>UPVEC_MAX_CP || column<0 || column>=(pv->columns-2)) {
+        return 0;
+    }
+    ncpv=(UPropsVectors *)pv;
+    row=_findRow(ncpv, c);
+    return row[2+column];
+}
+
+U_CAPI uint32_t * U_EXPORT2
+upvec_getRow(const UPropsVectors *pv, int32_t rowIndex,
+             UChar32 *pRangeStart, UChar32 *pRangeEnd) {
+    uint32_t *row;
+    int32_t columns;
+
+    if(pv->isCompacted || rowIndex<0 || rowIndex>=pv->rows) {
+        return NULL;
+    }
+
+    columns=pv->columns;
+    row=pv->v+rowIndex*columns;
+    if(pRangeStart!=NULL) {
+        *pRangeStart=(UChar32)row[0];
+    }
+    if(pRangeEnd!=NULL) {
+        *pRangeEnd=(UChar32)row[1]-1;
+    }
+    return row+2;
+}
+
+static int32_t U_CALLCONV
+upvec_compareRows(const void *context, const void *l, const void *r) {
+    const uint32_t *left=(const uint32_t *)l, *right=(const uint32_t *)r;
+    const UPropsVectors *pv=(const UPropsVectors *)context;
+    int32_t i, count, columns;
+
+    count=columns=pv->columns; /* includes start/limit columns */
+
+    /* start comparing after start/limit but wrap around to them */
+    i=2;
+    do {
+        if(left[i]!=right[i]) {
+            return left[i]<right[i] ? -1 : 1;
+        }
+        if(++i==columns) {
+            i=0;
+        }
+    } while(--count>0);
+
+    return 0;
+}
+
+U_CAPI void U_EXPORT2
+upvec_compact(UPropsVectors *pv, UPVecCompactHandler *handler, void *context, UErrorCode *pErrorCode) {
+    uint32_t *row;
+    int32_t i, columns, valueColumns, rows, count;
+    UChar32 start, limit;
+
+    /* argument checking */
+    if(U_FAILURE(*pErrorCode)) {
+        return;
+    }
+    if(handler==NULL) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    if(pv->isCompacted) {
+        return;
+    }
+
+    /* Set the flag now: Sorting and compacting destroys the builder data structure. */
+    pv->isCompacted=TRUE;
+
+    rows=pv->rows;
+    columns=pv->columns;
+    valueColumns=columns-2; /* not counting start & limit */
+
+    /* sort the properties vectors to find unique vector values */
+    uprv_sortArray(pv->v, rows, columns*4,
+                   upvec_compareRows, pv, FALSE, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        return;
+    }
+
+    /*
+     * Find and set the special values.
+     * This has to do almost the same work as the compaction below,
+     * to find the indexes where the special-value rows will move.
+     */
+    row=pv->v;
+    count=-valueColumns;
+    for(i=0; i<rows; ++i) {
+        start=(UChar32)row[0];
+
+        /* count a new values vector if it is different from the current one */
+        if(count<0 || 0!=uprv_memcmp(row+2, row-valueColumns, valueColumns*4)) {
+            count+=valueColumns;
+        }
+
+        if(start>=UPVEC_FIRST_SPECIAL_CP) {
+            handler(context, start, start, count, row+2, valueColumns, pErrorCode);
+            if(U_FAILURE(*pErrorCode)) {
+                return;
+            }
+        }
+
+        row+=columns;
+    }
+
+    /* count is at the beginning of the last vector, add valueColumns to include that last vector */
+    count+=valueColumns;
+
+    /* Call the handler once more to signal the start of delivering real values. */
+    handler(context, UPVEC_START_REAL_VALUES_CP, UPVEC_START_REAL_VALUES_CP,
+            count, row-valueColumns, valueColumns, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        return;
+    }
+
+    /*
+     * Move vector contents up to a contiguous array with only unique
+     * vector values, and call the handler function for each vector.
+     *
+     * This destroys the Properties Vector structure and replaces it
+     * with an array of just vector values.
+     */
+    row=pv->v;
+    count=-valueColumns;
+    for(i=0; i<rows; ++i) {
+        /* fetch these first before memmove() may overwrite them */
+        start=(UChar32)row[0];
+        limit=(UChar32)row[1];
+
+        /* add a new values vector if it is different from the current one */
+        if(count<0 || 0!=uprv_memcmp(row+2, pv->v+count, valueColumns*4)) {
+            count+=valueColumns;
+            uprv_memmove(pv->v+count, row+2, valueColumns*4);
+        }
+
+        if(start<UPVEC_FIRST_SPECIAL_CP) {
+            handler(context, start, limit-1, count, pv->v+count, valueColumns, pErrorCode);
+            if(U_FAILURE(*pErrorCode)) {
+                return;
+            }
+        }
+
+        row+=columns;
+    }
+
+    /* count is at the beginning of the last vector, add one to include that last vector */
+    pv->rows=count/valueColumns+1;
+}
+
+U_CAPI const uint32_t * U_EXPORT2
+upvec_getArray(const UPropsVectors *pv, int32_t *pRows, int32_t *pColumns) {
+    if(!pv->isCompacted) {
+        return NULL;
+    }
+    if(pRows!=NULL) {
+        *pRows=pv->rows;
+    }
+    if(pColumns!=NULL) {
+        *pColumns=pv->columns-2;
+    }
+    return pv->v;
+}
+
+U_CAPI uint32_t * U_EXPORT2
+upvec_cloneArray(const UPropsVectors *pv,
+                 int32_t *pRows, int32_t *pColumns, UErrorCode *pErrorCode) {
+    uint32_t *clonedArray;
+    int32_t byteLength;
+
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+    if(!pv->isCompacted) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return NULL;
+    }
+    byteLength=pv->rows*(pv->columns-2)*4;
+    clonedArray=(uint32_t *)uprv_malloc(byteLength);
+    if(clonedArray==NULL) {
+        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
+    }
+    uprv_memcpy(clonedArray, pv->v, byteLength);
+    if(pRows!=NULL) {
+        *pRows=pv->rows;
+    }
+    if(pColumns!=NULL) {
+        *pColumns=pv->columns-2;
+    }
+    return clonedArray;
+}
+
+U_CAPI UTrie2 * U_EXPORT2
+upvec_compactToUTrie2WithRowIndexes(UPropsVectors *pv, UErrorCode *pErrorCode) {
+    UPVecToUTrie2Context toUTrie2={ NULL };
+    upvec_compact(pv, upvec_compactToUTrie2Handler, &toUTrie2, pErrorCode);
+    utrie2_freeze(toUTrie2.trie, UTRIE2_16_VALUE_BITS, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        utrie2_close(toUTrie2.trie);
+        toUTrie2.trie=NULL;
+    }
+    return toUTrie2.trie;
+}
+
+/*
+ * TODO(markus): Add upvec_16BitsToUTrie2() function that enumerates all rows, extracts
+ * some 16-bit field and builds and returns a UTrie2.
+ */
+
+U_CAPI void U_CALLCONV
+upvec_compactToUTrieHandler(void *context,
+                            UChar32 start, UChar32 end,
+                            int32_t rowIndex, uint32_t *row, int32_t columns,
+                            UErrorCode *pErrorCode) {
+    UPVecToUTrieContext *toUTrie=(UPVecToUTrieContext *)context;
+    if(start<UPVEC_FIRST_SPECIAL_CP) {
+        if(!utrie_setRange32(toUTrie->newTrie, start, end+1, (uint32_t)rowIndex, TRUE)) {
+            *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
+        }
+    } else {
+        switch(start) {
+        case UPVEC_INITIAL_VALUE_CP:
+            toUTrie->initialValue=rowIndex;
+            break;
+        case UPVEC_START_REAL_VALUES_CP:
+            if(rowIndex>0xffff) {
+                /* too many rows for a 16-bit trie */
+                *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+            } else {
+                toUTrie->newTrie=utrie_open(NULL, NULL, toUTrie->capacity,
+                                            toUTrie->initialValue, toUTrie->initialValue,
+                                            toUTrie->latin1Linear);
+                if(toUTrie->newTrie==NULL) {
+                    *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+                }
+            }
+            break;
+        default:
+            break;
+        }
+    }
+}
+
+U_CAPI void U_CALLCONV
+upvec_compactToUTrie2Handler(void *context,
+                             UChar32 start, UChar32 end,
+                             int32_t rowIndex, uint32_t *row, int32_t columns,
+                             UErrorCode *pErrorCode) {
+    UPVecToUTrie2Context *toUTrie2=(UPVecToUTrie2Context *)context;
+    if(start<UPVEC_FIRST_SPECIAL_CP) {
+        utrie2_setRange32(toUTrie2->trie, start, end, (uint32_t)rowIndex, TRUE, pErrorCode);
+    } else {
+        switch(start) {
+        case UPVEC_INITIAL_VALUE_CP:
+            toUTrie2->initialValue=rowIndex;
+            break;
+        case UPVEC_ERROR_VALUE_CP:
+            toUTrie2->errorValue=rowIndex;
+            break;
+        case UPVEC_START_REAL_VALUES_CP:
+            toUTrie2->maxValue=rowIndex;
+            if(rowIndex>0xffff) {
+                /* too many rows for a 16-bit trie */
+                *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+            } else {
+                toUTrie2->trie=utrie2_open(toUTrie2->initialValue,
+                                           toUTrie2->errorValue, pErrorCode);
+            }
+            break;
+        default:
+            break;
+        }
+    }
+}
diff --git a/icu/source/common/propsvec.h b/icu/source/common/propsvec.h
new file mode 100644
index 0000000..2e47c8d
--- /dev/null
+++ b/icu/source/common/propsvec.h
@@ -0,0 +1,191 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2002-2009, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  propsvec.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2002feb22
+*   created by: Markus W. Scherer
+*
+*   Store bits (Unicode character properties) in bit set vectors.
+*/
+
+#ifndef __UPROPSVEC_H__
+#define __UPROPSVEC_H__
+
+#include "unicode/utypes.h"
+#include "utrie.h"
+#include "utrie2.h"
+
+U_CDECL_BEGIN
+
+/**
+ * Unicode Properties Vectors associated with code point ranges.
+ *
+ * Rows of uint32_t integers in a contiguous array store
+ * the range limits and the properties vectors.
+ *
+ * Logically, each row has a certain number of uint32_t values,
+ * which is set via the upvec_open() "columns" parameter.
+ *
+ * Internally, two additional columns are stored.
+ * In each internal row,
+ * row[0] contains the start code point and
+ * row[1] contains the limit code point,
+ * which is the start of the next range.
+ *
+ * Initially, there is only one "normal" row for
+ * range [0..0x110000[ with values 0.
+ * There are additional rows for special purposes, see UPVEC_FIRST_SPECIAL_CP.
+ *
+ * It would be possible to store only one range boundary per row,
+ * but self-contained rows allow to later sort them by contents.
+ */
+struct UPropsVectors;
+typedef struct UPropsVectors UPropsVectors;
+
+/*
+ * Special pseudo code points for storing the initialValue and the errorValue,
+ * which are used to initialize a UTrie2 or similar.
+ */
+#define UPVEC_FIRST_SPECIAL_CP 0x110000
+#define UPVEC_INITIAL_VALUE_CP 0x110000
+#define UPVEC_ERROR_VALUE_CP 0x110001
+#define UPVEC_MAX_CP 0x110001
+
+/*
+ * Special pseudo code point used in upvec_compact() signalling the end of
+ * delivering special values and the beginning of delivering real ones.
+ * Stable value, unlike UPVEC_MAX_CP which might grow over time.
+ */
+#define UPVEC_START_REAL_VALUES_CP 0x200000
+
+/*
+ * Open a UPropsVectors object.
+ * @param columns Number of value integers (uint32_t) per row.
+ */
+U_CAPI UPropsVectors * U_EXPORT2
+upvec_open(int32_t columns, UErrorCode *pErrorCode);
+
+U_CAPI void U_EXPORT2
+upvec_close(UPropsVectors *pv);
+
+/*
+ * In rows for code points [start..end], select the column,
+ * reset the mask bits and set the value bits (ANDed with the mask).
+ *
+ * Will set U_NO_WRITE_PERMISSION if called after upvec_compact().
+ */
+U_CAPI void U_EXPORT2
+upvec_setValue(UPropsVectors *pv,
+               UChar32 start, UChar32 end,
+               int32_t column,
+               uint32_t value, uint32_t mask,
+               UErrorCode *pErrorCode);
+
+/*
+ * Logically const but must not be used on the same pv concurrently!
+ * Always returns 0 if called after upvec_compact().
+ */
+U_CAPI uint32_t U_EXPORT2
+upvec_getValue(const UPropsVectors *pv, UChar32 c, int32_t column);
+
+/*
+ * pRangeStart and pRangeEnd can be NULL.
+ * @return NULL if rowIndex out of range and for illegal arguments,
+ *         or if called after upvec_compact()
+ */
+U_CAPI uint32_t * U_EXPORT2
+upvec_getRow(const UPropsVectors *pv, int32_t rowIndex,
+             UChar32 *pRangeStart, UChar32 *pRangeEnd);
+
+/*
+ * Compact the vectors:
+ * - modify the memory
+ * - keep only unique vectors
+ * - store them contiguously from the beginning of the memory
+ * - for each (non-unique) row, call the handler function
+ *
+ * The handler's rowIndex is the index of the row in the compacted
+ * memory block.
+ * (Therefore, it starts at 0 increases in increments of the columns value.)
+ *
+ * In a first phase, only special values are delivered (each exactly once),
+ * with start==end both equalling a special pseudo code point.
+ * Then the handler is called once more with start==end==UPVEC_START_REAL_VALUES_CP
+ * where rowIndex is the length of the compacted array,
+ * and the row is arbitrary (but not NULL).
+ * Then, in the second phase, the handler is called for each row of real values.
+ */
+typedef void U_CALLCONV
+UPVecCompactHandler(void *context,
+                    UChar32 start, UChar32 end,
+                    int32_t rowIndex, uint32_t *row, int32_t columns,
+                    UErrorCode *pErrorCode);
+
+U_CAPI void U_EXPORT2
+upvec_compact(UPropsVectors *pv, UPVecCompactHandler *handler, void *context, UErrorCode *pErrorCode);
+
+/*
+ * Get the vectors array after calling upvec_compact().
+ * The caller must not modify nor release the returned array.
+ * Returns NULL if called before upvec_compact().
+ */
+U_CAPI const uint32_t * U_EXPORT2
+upvec_getArray(const UPropsVectors *pv, int32_t *pRows, int32_t *pColumns);
+
+/*
+ * Get a clone of the vectors array after calling upvec_compact().
+ * The caller owns the returned array and must uprv_free() it.
+ * Returns NULL if called before upvec_compact().
+ */
+U_CAPI uint32_t * U_EXPORT2
+upvec_cloneArray(const UPropsVectors *pv,
+                 int32_t *pRows, int32_t *pColumns, UErrorCode *pErrorCode);
+
+/*
+ * Call upvec_compact(), create a 16-bit UTrie2 with indexes into the compacted
+ * vectors array, and freeze the trie.
+ */
+U_CAPI UTrie2 * U_EXPORT2
+upvec_compactToUTrie2WithRowIndexes(UPropsVectors *pv, UErrorCode *pErrorCode);
+
+struct UPVecToUTrieContext {
+    UNewTrie *newTrie;
+    int32_t capacity;
+    int32_t initialValue;
+    UBool latin1Linear;
+};
+typedef struct UPVecToUTrieContext UPVecToUTrieContext;
+
+/* context=UPVecToUTrieContext, creates the trie and stores the rowIndex values */
+U_CAPI void U_CALLCONV
+upvec_compactToUTrieHandler(void *context,
+                            UChar32 start, UChar32 end,
+                            int32_t rowIndex, uint32_t *row, int32_t columns,
+                            UErrorCode *pErrorCode);
+
+struct UPVecToUTrie2Context {
+    UTrie2 *trie;
+    int32_t initialValue;
+    int32_t errorValue;
+    int32_t maxValue;
+};
+typedef struct UPVecToUTrie2Context UPVecToUTrie2Context;
+
+/* context=UPVecToUTrie2Context, creates the trie and stores the rowIndex values */
+U_CAPI void U_CALLCONV
+upvec_compactToUTrie2Handler(void *context,
+                             UChar32 start, UChar32 end,
+                             int32_t rowIndex, uint32_t *row, int32_t columns,
+                             UErrorCode *pErrorCode);
+
+U_CDECL_END
+
+#endif
diff --git a/icu/source/common/punycode.c b/icu/source/common/punycode.c
new file mode 100644
index 0000000..5376625
--- /dev/null
+++ b/icu/source/common/punycode.c
@@ -0,0 +1,580 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2002-2003, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  punycode.c
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2002jan31
+*   created by: Markus W. Scherer
+*/
+
+
+/* This ICU code derived from: */
+/*
+punycode.c 0.4.0 (2001-Nov-17-Sat)
+http://www.cs.berkeley.edu/~amc/idn/
+Adam M. Costello
+http://www.nicemice.net/amc/
+
+Disclaimer and license
+
+    Regarding this entire document or any portion of it (including
+    the pseudocode and C code), the author makes no guarantees and
+    is not responsible for any damage resulting from its use.  The
+    author grants irrevocable permission to anyone to use, modify,
+    and distribute it in any way that does not diminish the rights
+    of anyone else to use, modify, and distribute it, provided that
+    redistributed derivative works do not contain misleading author or
+    version information.  Derivative works need not be licensed under
+    similar terms.
+*/
+/*
+ * ICU modifications:
+ * - ICU data types and coding conventions
+ * - ICU string buffer handling with implicit source lengths
+ *   and destination preflighting
+ * - UTF-16 handling
+ */
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_IDNA
+
+#include "ustr_imp.h"
+#include "cstring.h"
+#include "cmemory.h"
+#include "punycode.h"
+#include "unicode/ustring.h"
+
+
+/* Punycode ----------------------------------------------------------------- */
+
+/* Punycode parameters for Bootstring */
+#define BASE            36
+#define TMIN            1
+#define TMAX            26
+#define SKEW            38
+#define DAMP            700
+#define INITIAL_BIAS    72
+#define INITIAL_N       0x80
+
+/* "Basic" Unicode/ASCII code points */
+#define _HYPHEN         0X2d
+#define DELIMITER       _HYPHEN
+
+#define _ZERO_          0X30
+#define _NINE           0x39
+
+#define _SMALL_A        0X61
+#define _SMALL_Z        0X7a
+
+#define _CAPITAL_A      0X41
+#define _CAPITAL_Z      0X5a
+
+#define IS_BASIC(c) ((c)<0x80)
+#define IS_BASIC_UPPERCASE(c) (_CAPITAL_A<=(c) && (c)<=_CAPITAL_Z)
+
+/**
+ * digitToBasic() returns the basic code point whose value
+ * (when used for representing integers) is d, which must be in the
+ * range 0 to BASE-1. The lowercase form is used unless the uppercase flag is
+ * nonzero, in which case the uppercase form is used.
+ */
+static U_INLINE char
+digitToBasic(int32_t digit, UBool uppercase) {
+    /*  0..25 map to ASCII a..z or A..Z */
+    /* 26..35 map to ASCII 0..9         */
+    if(digit<26) {
+        if(uppercase) {
+            return (char)(_CAPITAL_A+digit);
+        } else {
+            return (char)(_SMALL_A+digit);
+        }
+    } else {
+        return (char)((_ZERO_-26)+digit);
+    }
+}
+
+/**
+ * basicToDigit[] contains the numeric value of a basic code
+ * point (for use in representing integers) in the range 0 to
+ * BASE-1, or -1 if b is does not represent a value.
+ */
+static const int8_t
+basicToDigit[256]={
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
+
+    -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+
+    -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+static U_INLINE char
+asciiCaseMap(char b, UBool uppercase) {
+    if(uppercase) {
+        if(_SMALL_A<=b && b<=_SMALL_Z) {
+            b-=(_SMALL_A-_CAPITAL_A);
+        }
+    } else {
+        if(_CAPITAL_A<=b && b<=_CAPITAL_Z) {
+            b+=(_SMALL_A-_CAPITAL_A);
+        }
+    }
+    return b;
+}
+
+/* Punycode-specific Bootstring code ---------------------------------------- */
+
+/*
+ * The following code omits the {parts} of the pseudo-algorithm in the spec
+ * that are not used with the Punycode parameter set.
+ */
+
+/* Bias adaptation function. */
+static int32_t
+adaptBias(int32_t delta, int32_t length, UBool firstTime) {
+    int32_t count;
+
+    if(firstTime) {
+        delta/=DAMP;
+    } else {
+        delta/=2;
+    }
+
+    delta+=delta/length;
+    for(count=0; delta>((BASE-TMIN)*TMAX)/2; count+=BASE) {
+        delta/=(BASE-TMIN);
+    }
+
+    return count+(((BASE-TMIN+1)*delta)/(delta+SKEW));
+}
+
+#define MAX_CP_COUNT    200
+
+U_CFUNC int32_t
+u_strToPunycode(const UChar *src, int32_t srcLength,
+                UChar *dest, int32_t destCapacity,
+                const UBool *caseFlags,
+                UErrorCode *pErrorCode) {
+
+    int32_t cpBuffer[MAX_CP_COUNT];
+    int32_t n, delta, handledCPCount, basicLength, destLength, bias, j, m, q, k, t, srcCPCount;
+    UChar c, c2;
+
+    /* argument checking */
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    if(src==NULL || srcLength<-1 || (dest==NULL && destCapacity!=0)) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    /*
+     * Handle the basic code points and
+     * convert extended ones to UTF-32 in cpBuffer (caseFlag in sign bit):
+     */
+    srcCPCount=destLength=0;
+    if(srcLength==-1) {
+        /* NUL-terminated input */
+        for(j=0; /* no condition */; ++j) {
+            if((c=src[j])==0) {
+                break;
+            }
+            if(srcCPCount==MAX_CP_COUNT) {
+                /* too many input code points */
+                *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+                return 0;
+            }
+            if(IS_BASIC(c)) {
+                cpBuffer[srcCPCount++]=0;
+                if(destLength<destCapacity) {
+                    dest[destLength]=
+                        caseFlags!=NULL ?
+                            asciiCaseMap((char)c, caseFlags[j]) :
+                            (char)c;
+                }
+                ++destLength;
+            } else {
+                n=(caseFlags!=NULL && caseFlags[j])<<31L;
+                if(UTF_IS_SINGLE(c)) {
+                    n|=c;
+                } else if(UTF_IS_LEAD(c) && UTF_IS_TRAIL(c2=src[j+1])) {
+                    ++j;
+                    n|=(int32_t)UTF16_GET_PAIR_VALUE(c, c2);
+                } else {
+                    /* error: unmatched surrogate */
+                    *pErrorCode=U_INVALID_CHAR_FOUND;
+                    return 0;
+                }
+                cpBuffer[srcCPCount++]=n;
+            }
+        }
+    } else {
+        /* length-specified input */
+        for(j=0; j<srcLength; ++j) {
+            if(srcCPCount==MAX_CP_COUNT) {
+                /* too many input code points */
+                *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
+                return 0;
+            }
+            c=src[j];
+            if(IS_BASIC(c)) {
+                if(destLength<destCapacity) {
+                    cpBuffer[srcCPCount++]=0;
+                    dest[destLength]=
+                        caseFlags!=NULL ?
+                            asciiCaseMap((char)c, caseFlags[j]) :
+                            (char)c;
+                }
+                ++destLength;
+            } else {
+                n=(caseFlags!=NULL && caseFlags[j])<<31L;
+                if(UTF_IS_SINGLE(c)) {
+                    n|=c;
+                } else if(UTF_IS_LEAD(c) && (j+1)<srcLength && UTF_IS_TRAIL(c2=src[j+1])) {
+                    ++j;
+                    n|=(int32_t)UTF16_GET_PAIR_VALUE(c, c2);
+                } else {
+                    /* error: unmatched surrogate */
+                    *pErrorCode=U_INVALID_CHAR_FOUND;
+                    return 0;
+                }
+                cpBuffer[srcCPCount++]=n;
+            }
+        }
+    }
+
+    /* Finish the basic string - if it is not empty - with a delimiter. */
+    basicLength=destLength;
+    if(basicLength>0) {
+        if(destLength<destCapacity) {
+            dest[destLength]=DELIMITER;
+        }
+        ++destLength;
+    }
+
+    /*
+     * handledCPCount is the number of code points that have been handled
+     * basicLength is the number of basic code points
+     * destLength is the number of chars that have been output
+     */
+
+    /* Initialize the state: */
+    n=INITIAL_N;
+    delta=0;
+    bias=INITIAL_BIAS;
+
+    /* Main encoding loop: */
+    for(handledCPCount=basicLength; handledCPCount<srcCPCount; /* no op */) {
+        /*
+         * All non-basic code points < n have been handled already.
+         * Find the next larger one:
+         */
+        for(m=0x7fffffff, j=0; j<srcCPCount; ++j) {
+            q=cpBuffer[j]&0x7fffffff; /* remove case flag from the sign bit */
+            if(n<=q && q<m) {
+                m=q;
+            }
+        }
+
+        /*
+         * Increase delta enough to advance the decoder's
+         * <n,i> state to <m,0>, but guard against overflow:
+         */
+        if(m-n>(0x7fffffff-MAX_CP_COUNT-delta)/(handledCPCount+1)) {
+            *pErrorCode=U_INTERNAL_PROGRAM_ERROR;
+            return 0;
+        }
+        delta+=(m-n)*(handledCPCount+1);
+        n=m;
+
+        /* Encode a sequence of same code points n */
+        for(j=0; j<srcCPCount; ++j) {
+            q=cpBuffer[j]&0x7fffffff; /* remove case flag from the sign bit */
+            if(q<n) {
+                ++delta;
+            } else if(q==n) {
+                /* Represent delta as a generalized variable-length integer: */
+                for(q=delta, k=BASE; /* no condition */; k+=BASE) {
+
+                    /** RAM: comment out the old code for conformance with draft-ietf-idn-punycode-03.txt   
+
+                    t=k-bias;
+                    if(t<TMIN) {
+                        t=TMIN;
+                    } else if(t>TMAX) {
+                        t=TMAX;
+                    }
+                    */
+                    
+                    t=k-bias;
+                    if(t<TMIN) {
+                        t=TMIN;
+                    } else if(k>=(bias+TMAX)) {
+                        t=TMAX;
+                    }
+
+                    if(q<t) {
+                        break;
+                    }
+
+                    if(destLength<destCapacity) {
+                        dest[destLength++]=digitToBasic(t+(q-t)%(BASE-t), 0);
+                    }
+                    q=(q-t)/(BASE-t);
+                }
+
+                if(destLength<destCapacity) {
+                    dest[destLength++]=digitToBasic(q, (UBool)(cpBuffer[j]<0));
+                }
+                bias=adaptBias(delta, handledCPCount+1, (UBool)(handledCPCount==basicLength));
+                delta=0;
+                ++handledCPCount;
+            }
+        }
+
+        ++delta;
+        ++n;
+    }
+
+    return u_terminateUChars(dest, destCapacity, destLength, pErrorCode);
+}
+
+U_CFUNC int32_t
+u_strFromPunycode(const UChar *src, int32_t srcLength,
+                  UChar *dest, int32_t destCapacity,
+                  UBool *caseFlags,
+                  UErrorCode *pErrorCode) {
+    int32_t n, destLength, i, bias, basicLength, j, in, oldi, w, k, digit, t,
+            destCPCount, firstSupplementaryIndex, cpLength;
+    UChar b;
+
+    /* argument checking */
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    if(src==NULL || srcLength<-1 || (dest==NULL && destCapacity!=0)) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    if(srcLength==-1) {
+        srcLength=u_strlen(src);
+    }
+
+    /*
+     * Handle the basic code points:
+     * Let basicLength be the number of input code points
+     * before the last delimiter, or 0 if there is none,
+     * then copy the first basicLength code points to the output.
+     *
+     * The two following loops iterate backward.
+     */
+    for(j=srcLength; j>0;) {
+        if(src[--j]==DELIMITER) {
+            break;
+        }
+    }
+    destLength=basicLength=destCPCount=j;
+
+    while(j>0) {
+        b=src[--j];
+        if(!IS_BASIC(b)) {
+            *pErrorCode=U_INVALID_CHAR_FOUND;
+            return 0;
+        }
+
+        if(j<destCapacity) {
+            dest[j]=(UChar)b;
+
+            if(caseFlags!=NULL) {
+                caseFlags[j]=IS_BASIC_UPPERCASE(b);
+            }
+        }
+    }
+
+    /* Initialize the state: */
+    n=INITIAL_N;
+    i=0;
+    bias=INITIAL_BIAS;
+    firstSupplementaryIndex=1000000000;
+
+    /*
+     * Main decoding loop:
+     * Start just after the last delimiter if any
+     * basic code points were copied; start at the beginning otherwise.
+     */
+    for(in=basicLength>0 ? basicLength+1 : 0; in<srcLength; /* no op */) {
+        /*
+         * in is the index of the next character to be consumed, and
+         * destCPCount is the number of code points in the output array.
+         *
+         * Decode a generalized variable-length integer into delta,
+         * which gets added to i.  The overflow checking is easier
+         * if we increase i as we go, then subtract off its starting
+         * value at the end to obtain delta.
+         */
+        for(oldi=i, w=1, k=BASE; /* no condition */; k+=BASE) {
+            if(in>=srcLength) {
+                *pErrorCode=U_ILLEGAL_CHAR_FOUND;
+                return 0;
+            }
+
+            digit=basicToDigit[(uint8_t)src[in++]];
+            if(digit<0) {
+                *pErrorCode=U_INVALID_CHAR_FOUND;
+                return 0;
+            }
+            if(digit>(0x7fffffff-i)/w) {
+                /* integer overflow */
+                *pErrorCode=U_ILLEGAL_CHAR_FOUND;
+                return 0;
+            }
+
+            i+=digit*w;
+            /** RAM: comment out the old code for conformance with draft-ietf-idn-punycode-03.txt  
+            t=k-bias;
+            if(t<TMIN) {
+                t=TMIN;
+            } else if(t>TMAX) {
+                t=TMAX;
+            }
+            */
+            t=k-bias;
+            if(t<TMIN) {
+                t=TMIN;
+            } else if(k>=(bias+TMAX)) {
+                t=TMAX;
+            }
+            if(digit<t) {
+                break;
+            }
+
+            if(w>0x7fffffff/(BASE-t)) {
+                /* integer overflow */
+                *pErrorCode=U_ILLEGAL_CHAR_FOUND;
+                return 0;
+            }
+            w*=BASE-t;
+        }
+
+        /*
+         * Modification from sample code:
+         * Increments destCPCount here,
+         * where needed instead of in for() loop tail.
+         */
+        ++destCPCount;
+        bias=adaptBias(i-oldi, destCPCount, (UBool)(oldi==0));
+
+        /*
+         * i was supposed to wrap around from (incremented) destCPCount to 0,
+         * incrementing n each time, so we'll fix that now:
+         */
+        if(i/destCPCount>(0x7fffffff-n)) {
+            /* integer overflow */
+            *pErrorCode=U_ILLEGAL_CHAR_FOUND;
+            return 0;
+        }
+
+        n+=i/destCPCount;
+        i%=destCPCount;
+        /* not needed for Punycode: */
+        /* if (decode_digit(n) <= BASE) return punycode_invalid_input; */
+
+        if(n>0x10ffff || UTF_IS_SURROGATE(n)) {
+            /* Unicode code point overflow */
+            *pErrorCode=U_ILLEGAL_CHAR_FOUND;
+            return 0;
+        }
+
+        /* Insert n at position i of the output: */
+        cpLength=UTF_CHAR_LENGTH(n);
+        if((destLength+cpLength)<destCapacity) {
+            int32_t codeUnitIndex;
+
+            /*
+             * Handle indexes when supplementary code points are present.
+             *
+             * In almost all cases, there will be only BMP code points before i
+             * and even in the entire string.
+             * This is handled with the same efficiency as with UTF-32.
+             *
+             * Only the rare cases with supplementary code points are handled
+             * more slowly - but not too bad since this is an insertion anyway.
+             */
+            if(i<=firstSupplementaryIndex) {
+                codeUnitIndex=i;
+                if(cpLength>1) {
+                    firstSupplementaryIndex=codeUnitIndex;
+                } else {
+                    ++firstSupplementaryIndex;
+                }
+            } else {
+                codeUnitIndex=firstSupplementaryIndex;
+                UTF_FWD_N(dest, codeUnitIndex, destLength, i-codeUnitIndex);
+            }
+
+            /* use the UChar index codeUnitIndex instead of the code point index i */
+            if(codeUnitIndex<destLength) {
+                uprv_memmove(dest+codeUnitIndex+cpLength,
+                             dest+codeUnitIndex,
+                             (destLength-codeUnitIndex)*U_SIZEOF_UCHAR);
+                if(caseFlags!=NULL) {
+                    uprv_memmove(caseFlags+codeUnitIndex+cpLength,
+                                 caseFlags+codeUnitIndex,
+                                 destLength-codeUnitIndex);
+                }
+            }
+            if(cpLength==1) {
+                /* BMP, insert one code unit */
+                dest[codeUnitIndex]=(UChar)n;
+            } else {
+                /* supplementary character, insert two code units */
+                dest[codeUnitIndex]=UTF16_LEAD(n);
+                dest[codeUnitIndex+1]=UTF16_TRAIL(n);
+            }
+            if(caseFlags!=NULL) {
+                /* Case of last character determines uppercase flag: */
+                caseFlags[codeUnitIndex]=IS_BASIC_UPPERCASE(src[in-1]);
+                if(cpLength==2) {
+                    caseFlags[codeUnitIndex+1]=FALSE;
+                }
+            }
+        }
+        destLength+=cpLength;
+        ++i;
+    }
+
+    return u_terminateUChars(dest, destCapacity, destLength, pErrorCode);
+}
+
+/* ### check notes on overflow handling - only necessary if not IDNA? are these Punycode functions to be public? */
+
+#endif /* #if !UCONFIG_NO_IDNA */
diff --git a/icu/source/common/punycode.h b/icu/source/common/punycode.h
new file mode 100644
index 0000000..21ae91d
--- /dev/null
+++ b/icu/source/common/punycode.h
@@ -0,0 +1,118 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2002-2003, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  punycode.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2002jan31
+*   created by: Markus W. Scherer
+*/
+
+/* This ICU code derived from: */
+/*
+punycode.c 0.4.0 (2001-Nov-17-Sat)
+http://www.cs.berkeley.edu/~amc/idn/
+Adam M. Costello
+http://www.nicemice.net/amc/
+*/
+
+#ifndef __PUNYCODE_H__
+#define __PUNYCODE_H__
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_IDNA
+
+/**
+ * u_strToPunycode() converts Unicode to Punycode.
+ *
+ * The input string must not contain single, unpaired surrogates.
+ * The output will be represented as an array of ASCII code points.
+ *
+ * The output string is NUL-terminated according to normal ICU
+ * string output rules.
+ *
+ * @param src Input Unicode string.
+ *            This function handles a limited amount of code points
+ *            (the limit is >=64).
+ *            U_INDEX_OUTOFBOUNDS_ERROR is set if the limit is exceeded.
+ * @param srcLength Number of UChars in src, or -1 if NUL-terminated.
+ * @param dest Output Punycode array.
+ * @param destCapacity Size of dest.
+ * @param caseFlags Vector of boolean values, one per input UChar,
+ *                  indicating that the corresponding character is to be
+ *                  marked for the decoder optionally
+ *                  uppercasing (TRUE) or lowercasing (FALSE)
+ *                  the character.
+ *                  ASCII characters are output directly in the case as marked.
+ *                  Flags corresponding to trail surrogates are ignored.
+ *                  If caseFlags==NULL then input characters are not
+ *                  case-mapped.
+ * @param pErrorCode ICU in/out error code parameter.
+ *                   U_INVALID_CHAR_FOUND if src contains
+ *                   unmatched single surrogates.
+ *                   U_INDEX_OUTOFBOUNDS_ERROR if src contains
+ *                   too many code points.
+ * @return Number of ASCII characters in puny.
+ *
+ * @see u_strFromPunycode
+ */
+U_CFUNC int32_t
+u_strToPunycode(const UChar *src, int32_t srcLength,
+                UChar *dest, int32_t destCapacity,
+                const UBool *caseFlags,
+                UErrorCode *pErrorCode);
+
+/**
+ * u_strFromPunycode() converts Punycode to Unicode.
+ * The Unicode string will be at most as long (in UChars)
+ * than the Punycode string (in chars).
+ *
+ * @param src Input Punycode string.
+ * @param srcLength Length of puny, or -1 if NUL-terminated
+ * @param dest Output Unicode string buffer.
+ * @param destCapacity Size of dest in number of UChars,
+ *                     and of caseFlags in numbers of UBools.
+ * @param caseFlags Output array for case flags as
+ *                  defined by the Punycode string.
+ *                  The caller should uppercase (TRUE) or lowercase (FASLE)
+ *                  the corresponding character in dest.
+ *                  For supplementary characters, only the lead surrogate
+ *                  is marked, and FALSE is stored for the trail surrogate.
+ *                  This is redundant and not necessary for ASCII characters
+ *                  because they are already in the case indicated.
+ *                  Can be NULL if the case flags are not needed.
+ * @param pErrorCode ICU in/out error code parameter.
+ *                   U_INVALID_CHAR_FOUND if a non-ASCII character
+ *                   precedes the last delimiter ('-'),
+ *                   or if an invalid character (not a-zA-Z0-9) is found
+ *                   after the last delimiter.
+ *                   U_ILLEGAL_CHAR_FOUND if the delta sequence is ill-formed.
+ * @return Number of UChars written to dest.
+ *
+ * @see u_strToPunycode
+ */
+U_CFUNC int32_t
+u_strFromPunycode(const UChar *src, int32_t srcLength,
+                  UChar *dest, int32_t destCapacity,
+                  UBool *caseFlags,
+                  UErrorCode *pErrorCode);
+
+#endif /* #if !UCONFIG_NO_IDNA */
+
+#endif
+
+/*
+ * Hey, Emacs, please set the following:
+ *
+ * Local Variables:
+ * indent-tabs-mode: nil
+ * End:
+ *
+ */
diff --git a/icu/source/common/putil.c b/icu/source/common/putil.c
new file mode 100644
index 0000000..6c13bb0
--- /dev/null
+++ b/icu/source/common/putil.c
@@ -0,0 +1,2149 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1997-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+*  FILE NAME : putil.c (previously putil.cpp and ptypes.cpp)
+*
+*   Date        Name        Description
+*   04/14/97    aliu        Creation.
+*   04/24/97    aliu        Added getDefaultDataDirectory() and
+*                            getDefaultLocaleID().
+*   04/28/97    aliu        Rewritten to assume Unix and apply general methods
+*                            for assumed case.  Non-UNIX platforms must be
+*                            special-cased.  Rewrote numeric methods dealing
+*                            with NaN and Infinity to be platform independent
+*                             over all IEEE 754 platforms.
+*   05/13/97    aliu        Restored sign of timezone
+*                            (semantics are hours West of GMT)
+*   06/16/98    erm         Added IEEE_754 stuff, cleaned up isInfinite, isNan,
+*                             nextDouble..
+*   07/22/98    stephen     Added remainder, max, min, trunc
+*   08/13/98    stephen     Added isNegativeInfinity, isPositiveInfinity
+*   08/24/98    stephen     Added longBitsFromDouble
+*   09/08/98    stephen     Minor changes for Mac Port
+*   03/02/99    stephen     Removed openFile().  Added AS400 support.
+*                            Fixed EBCDIC tables
+*   04/15/99    stephen     Converted to C.
+*   06/28/99    stephen     Removed mutex locking in u_isBigEndian().
+*   08/04/99    jeffrey R.  Added OS/2 changes
+*   11/15/99    helena      Integrated S/390 IEEE support.
+*   04/26/01    Barry N.    OS/400 support for uprv_getDefaultLocaleID
+*   08/15/01    Steven H.   OS/400 support for uprv_getDefaultCodepage
+*   01/03/08    Steven L.   Fake Time Support
+******************************************************************************
+*/
+
+/* Define _XOPEN_SOURCE for Solaris and friends. */
+/* NetBSD needs it to be >= 4 */
+#if !defined(_XOPEN_SOURCE)
+#if __STDC_VERSION__ >= 199901L
+/* It is invalid to compile an XPG3, XPG4, XPG4v2 or XPG5 application using c99 on Solaris */
+#define _XOPEN_SOURCE 600
+#else
+#define _XOPEN_SOURCE 4
+#endif
+#endif
+
+/* Make sure things like readlink and such functions work.
+Poorly upgraded Solaris machines can't have this defined.
+Cleanly installed Solaris can use this #define.
+*/
+#if !defined(_XOPEN_SOURCE_EXTENDED) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ >= 199901L)
+#define _XOPEN_SOURCE_EXTENDED 1
+#endif
+
+/* include ICU headers */
+#include "unicode/utypes.h"
+#include "unicode/putil.h"
+#include "unicode/ustring.h"
+#include "putilimp.h"
+#include "uassert.h"
+#include "umutex.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "locmap.h"
+#include "ucln_cmn.h"
+
+/* Include standard headers. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <locale.h>
+#include <float.h>
+#include <time.h>
+
+/* include system headers */
+#ifdef U_WINDOWS
+#   define WIN32_LEAN_AND_MEAN
+#   define VC_EXTRALEAN
+#   define NOUSER
+#   define NOSERVICE
+#   define NOIME
+#   define NOMCX
+#   include <windows.h>
+#   include "wintz.h"
+#elif defined(U_CYGWIN) && defined(__STRICT_ANSI__)
+/* tzset isn't defined in strict ANSI on Cygwin. */
+#   undef __STRICT_ANSI__
+#elif defined(OS400)
+#   include <float.h>
+#   include <qusec.h>       /* error code structure */
+#   include <qusrjobi.h>
+#   include <qliept.h>      /* EPT_CALL macro  - this include must be after all other "QSYSINCs" */
+#   include <mih/testptr.h> /* For uprv_maximumPtr */
+#elif defined(XP_MAC)
+#   include <Files.h>
+#   include <IntlResources.h>
+#   include <Script.h>
+#   include <Folders.h>
+#   include <MacTypes.h>
+#   include <TextUtils.h>
+#   define ICU_NO_USER_DATA_OVERRIDE 1
+#elif defined(OS390)
+#include "unicode/ucnv.h"   /* Needed for UCNV_SWAP_LFNL_OPTION_STRING */
+#elif defined(U_DARWIN) || defined(U_LINUX) || defined(U_BSD)
+#include <limits.h>
+#include <unistd.h>
+#elif defined(U_QNX)
+#include <sys/neutrino.h>
+#elif defined(U_SOLARIS)
+# ifndef _XPG4_2
+#  define _XPG4_2
+# endif
+#endif
+
+
+#if defined(U_DARWIN)
+#include <TargetConditionals.h>
+#endif
+
+#ifndef U_WINDOWS
+#include <sys/time.h>
+#endif
+
+/*
+ * Only include langinfo.h if we have a way to get the codeset. If we later
+ * depend on more feature, we can test on U_HAVE_NL_LANGINFO.
+ *
+ */
+
+#if U_HAVE_NL_LANGINFO_CODESET
+#include <langinfo.h>
+#endif
+
+/**
+ * Simple things (presence of functions, etc) should just go in configure.in and be added to
+ * icucfg.h via autoheader.
+ */
+#if defined(HAVE_CONFIG_H)
+#include "icucfg.h"
+#endif
+
+/* Define the extension for data files, again... */
+#define DATA_TYPE "dat"
+
+/* Leave this copyright notice here! */
+static const char copyright[] = U_COPYRIGHT_STRING;
+
+/* floating point implementations ------------------------------------------- */
+
+/* We return QNAN rather than SNAN*/
+#define SIGN 0x80000000U
+
+/* Make it easy to define certain types of constants */
+typedef union {
+    int64_t i64; /* This must be defined first in order to allow the initialization to work. This is a C89 feature. */
+    double d64;
+} BitPatternConversion;
+static const BitPatternConversion gNan = { (int64_t) INT64_C(0x7FF8000000000000) };
+static const BitPatternConversion gInf = { (int64_t) INT64_C(0x7FF0000000000000) };
+
+/*---------------------------------------------------------------------------
+  Platform utilities
+  Our general strategy is to assume we're on a POSIX platform.  Platforms which
+  are non-POSIX must declare themselves so.  The default POSIX implementation
+  will sometimes work for non-POSIX platforms as well (e.g., the NaN-related
+  functions).
+  ---------------------------------------------------------------------------*/
+
+#if defined(U_WINDOWS) || defined(XP_MAC) || defined(OS400)
+#   undef U_POSIX_LOCALE
+#else
+#   define U_POSIX_LOCALE    1
+#endif
+
+/*
+    WARNING! u_topNBytesOfDouble and u_bottomNBytesOfDouble
+    can't be properly optimized by the gcc compiler sometimes (i.e. gcc 3.2).
+*/
+#if !IEEE_754
+static char*
+u_topNBytesOfDouble(double* d, int n)
+{
+#if U_IS_BIG_ENDIAN
+    return (char*)d;
+#else
+    return (char*)(d + 1) - n;
+#endif
+}
+#endif
+
+static char*
+u_bottomNBytesOfDouble(double* d, int n)
+{
+#if U_IS_BIG_ENDIAN
+    return (char*)(d + 1) - n;
+#else
+    return (char*)d;
+#endif
+}
+
+#if defined (U_DEBUG_FAKETIME)
+/* Override the clock to test things without having to move the system clock.
+ * Assumes POSIX gettimeofday() will function
+ */
+UDate fakeClock_t0 = 0; /** Time to start the clock from **/
+UDate fakeClock_dt = 0; /** Offset (fake time - real time) **/
+UBool fakeClock_set = FALSE; /** True if fake clock has spun up **/
+static UMTX fakeClockMutex = NULL;
+
+static UDate getUTCtime_real() {
+    struct timeval posixTime;
+    gettimeofday(&posixTime, NULL);
+    return (UDate)(((int64_t)posixTime.tv_sec * U_MILLIS_PER_SECOND) + (posixTime.tv_usec/1000));
+}
+
+static UDate getUTCtime_fake() {
+    umtx_lock(&fakeClockMutex);
+    if(!fakeClock_set) {
+        UDate real = getUTCtime_real();
+        const char *fake_start = getenv("U_FAKETIME_START");
+        if(fake_start!=NULL) {
+            sscanf(fake_start,"%lf",&fakeClock_t0);
+        }
+        fakeClock_dt = fakeClock_t0 - real;
+        fprintf(stderr,"U_DEBUG_FAKETIME was set at compile time, so the ICU clock will start at a preset value\n"
+                       "U_FAKETIME_START=%.0f (%s) for an offset of %.0f ms from the current time %.0f\n",
+                            fakeClock_t0, fake_start, fakeClock_dt, real);
+        fakeClock_set = TRUE;
+    }
+    umtx_unlock(&fakeClockMutex);
+
+    return getUTCtime_real() + fakeClock_dt;
+}
+#endif
+
+#if defined(U_WINDOWS)
+typedef union {
+    int64_t int64;
+    FILETIME fileTime;
+} FileTimeConversion;   /* This is like a ULARGE_INTEGER */
+
+/* Number of 100 nanoseconds from 1/1/1601 to 1/1/1970 */
+#define EPOCH_BIAS  INT64_C(116444736000000000)
+#define HECTONANOSECOND_PER_MILLISECOND   10000
+
+#endif
+
+/*---------------------------------------------------------------------------
+  Universal Implementations
+  These are designed to work on all platforms.  Try these, and if they
+  don't work on your platform, then special case your platform with new
+  implementations.
+---------------------------------------------------------------------------*/
+
+/* Return UTC (GMT) time measured in milliseconds since 0:00 on 1/1/70.*/
+U_CAPI UDate U_EXPORT2
+uprv_getUTCtime()
+{
+#if defined(U_DEBUG_FAKETIME)
+    return getUTCtime_fake(); /* Hook for overriding the clock */
+#elif defined(XP_MAC)
+    time_t t, t1, t2;
+    struct tm tmrec;
+
+    uprv_memset( &tmrec, 0, sizeof(tmrec) );
+    tmrec.tm_year = 70;
+    tmrec.tm_mon = 0;
+    tmrec.tm_mday = 1;
+    t1 = mktime(&tmrec);    /* seconds of 1/1/1970*/
+
+    time(&t);
+    uprv_memcpy( &tmrec, gmtime(&t), sizeof(tmrec) );
+    t2 = mktime(&tmrec);    /* seconds of current GMT*/
+    return (UDate)(t2 - t1) * U_MILLIS_PER_SECOND;         /* GMT (or UTC) in seconds since 1970*/
+#elif defined(U_WINDOWS)
+
+    FileTimeConversion winTime;
+    GetSystemTimeAsFileTime(&winTime.fileTime);
+    return (UDate)((winTime.int64 - EPOCH_BIAS) / HECTONANOSECOND_PER_MILLISECOND);
+#else
+
+#if defined(HAVE_GETTIMEOFDAY)
+    struct timeval posixTime;
+    gettimeofday(&posixTime, NULL);
+    return (UDate)(((int64_t)posixTime.tv_sec * U_MILLIS_PER_SECOND) + (posixTime.tv_usec/1000));
+#else
+    time_t epochtime;
+    time(&epochtime);
+    return (UDate)epochtime * U_MILLIS_PER_SECOND;
+#endif
+
+#endif
+}
+
+/*-----------------------------------------------------------------------------
+  IEEE 754
+  These methods detect and return NaN and infinity values for doubles
+  conforming to IEEE 754.  Platforms which support this standard include X86,
+  Mac 680x0, Mac PowerPC, AIX RS/6000, and most others.
+  If this doesn't work on your platform, you have non-IEEE floating-point, and
+  will need to code your own versions.  A naive implementation is to return 0.0
+  for getNaN and getInfinity, and false for isNaN and isInfinite.
+  ---------------------------------------------------------------------------*/
+
+U_CAPI UBool U_EXPORT2
+uprv_isNaN(double number)
+{
+#if IEEE_754
+    BitPatternConversion convertedNumber;
+    convertedNumber.d64 = number;
+    /* Infinity is 0x7FF0000000000000U. Anything greater than that is a NaN */
+    return (UBool)((convertedNumber.i64 & U_INT64_MAX) > gInf.i64);
+
+#elif defined(OS390)
+    uint32_t highBits = *(uint32_t*)u_topNBytesOfDouble(&number,
+                        sizeof(uint32_t));
+    uint32_t lowBits  = *(uint32_t*)u_bottomNBytesOfDouble(&number,
+                        sizeof(uint32_t));
+
+    return ((highBits & 0x7F080000L) == 0x7F080000L) &&
+      (lowBits == 0x00000000L);
+
+#else
+    /* If your platform doesn't support IEEE 754 but *does* have an NaN value,*/
+    /* you'll need to replace this default implementation with what's correct*/
+    /* for your platform.*/
+    return number != number;
+#endif
+}
+
+U_CAPI UBool U_EXPORT2
+uprv_isInfinite(double number)
+{
+#if IEEE_754
+    BitPatternConversion convertedNumber;
+    convertedNumber.d64 = number;
+    /* Infinity is exactly 0x7FF0000000000000U. */
+    return (UBool)((convertedNumber.i64 & U_INT64_MAX) == gInf.i64);
+#elif defined(OS390)
+    uint32_t highBits = *(uint32_t*)u_topNBytesOfDouble(&number,
+                        sizeof(uint32_t));
+    uint32_t lowBits  = *(uint32_t*)u_bottomNBytesOfDouble(&number,
+                        sizeof(uint32_t));
+
+    return ((highBits  & ~SIGN) == 0x70FF0000L) && (lowBits == 0x00000000L);
+
+#else
+    /* If your platform doesn't support IEEE 754 but *does* have an infinity*/
+    /* value, you'll need to replace this default implementation with what's*/
+    /* correct for your platform.*/
+    return number == (2.0 * number);
+#endif
+}
+
+U_CAPI UBool U_EXPORT2
+uprv_isPositiveInfinity(double number)
+{
+#if IEEE_754 || defined(OS390)
+    return (UBool)(number > 0 && uprv_isInfinite(number));
+#else
+    return uprv_isInfinite(number);
+#endif
+}
+
+U_CAPI UBool U_EXPORT2
+uprv_isNegativeInfinity(double number)
+{
+#if IEEE_754 || defined(OS390)
+    return (UBool)(number < 0 && uprv_isInfinite(number));
+
+#else
+    uint32_t highBits = *(uint32_t*)u_topNBytesOfDouble(&number,
+                        sizeof(uint32_t));
+    return((highBits & SIGN) && uprv_isInfinite(number));
+
+#endif
+}
+
+U_CAPI double U_EXPORT2
+uprv_getNaN()
+{
+#if IEEE_754 || defined(OS390)
+    return gNan.d64;
+#else
+    /* If your platform doesn't support IEEE 754 but *does* have an NaN value,*/
+    /* you'll need to replace this default implementation with what's correct*/
+    /* for your platform.*/
+    return 0.0;
+#endif
+}
+
+U_CAPI double U_EXPORT2
+uprv_getInfinity()
+{
+#if IEEE_754 || defined(OS390)
+    return gInf.d64;
+#else
+    /* If your platform doesn't support IEEE 754 but *does* have an infinity*/
+    /* value, you'll need to replace this default implementation with what's*/
+    /* correct for your platform.*/
+    return 0.0;
+#endif
+}
+
+U_CAPI double U_EXPORT2
+uprv_floor(double x)
+{
+    return floor(x);
+}
+
+U_CAPI double U_EXPORT2
+uprv_ceil(double x)
+{
+    return ceil(x);
+}
+
+U_CAPI double U_EXPORT2
+uprv_round(double x)
+{
+    return uprv_floor(x + 0.5);
+}
+
+U_CAPI double U_EXPORT2
+uprv_fabs(double x)
+{
+    return fabs(x);
+}
+
+U_CAPI double U_EXPORT2
+uprv_modf(double x, double* y)
+{
+    return modf(x, y);
+}
+
+U_CAPI double U_EXPORT2
+uprv_fmod(double x, double y)
+{
+    return fmod(x, y);
+}
+
+U_CAPI double U_EXPORT2
+uprv_pow(double x, double y)
+{
+    /* This is declared as "double pow(double x, double y)" */
+    return pow(x, y);
+}
+
+U_CAPI double U_EXPORT2
+uprv_pow10(int32_t x)
+{
+    return pow(10.0, (double)x);
+}
+
+U_CAPI double U_EXPORT2
+uprv_fmax(double x, double y)
+{
+#if IEEE_754
+    int32_t lowBits;
+
+    /* first handle NaN*/
+    if(uprv_isNaN(x) || uprv_isNaN(y))
+        return uprv_getNaN();
+
+    /* check for -0 and 0*/
+    lowBits = *(uint32_t*) u_bottomNBytesOfDouble(&x, sizeof(uint32_t));
+    if(x == 0.0 && y == 0.0 && (lowBits & SIGN))
+        return y;
+
+#endif
+
+    /* this should work for all flt point w/o NaN and Infpecial cases */
+    return (x > y ? x : y);
+}
+
+U_CAPI double U_EXPORT2
+uprv_fmin(double x, double y)
+{
+#if IEEE_754
+    int32_t lowBits;
+
+    /* first handle NaN*/
+    if(uprv_isNaN(x) || uprv_isNaN(y))
+        return uprv_getNaN();
+
+    /* check for -0 and 0*/
+    lowBits = *(uint32_t*) u_bottomNBytesOfDouble(&y, sizeof(uint32_t));
+    if(x == 0.0 && y == 0.0 && (lowBits & SIGN))
+        return y;
+
+#endif
+
+    /* this should work for all flt point w/o NaN and Inf special cases */
+    return (x > y ? y : x);
+}
+
+/**
+ * Truncates the given double.
+ * trunc(3.3) = 3.0, trunc (-3.3) = -3.0
+ * This is different than calling floor() or ceil():
+ * floor(3.3) = 3, floor(-3.3) = -4
+ * ceil(3.3) = 4, ceil(-3.3) = -3
+ */
+U_CAPI double U_EXPORT2
+uprv_trunc(double d)
+{
+#if IEEE_754
+    int32_t lowBits;
+
+    /* handle error cases*/
+    if(uprv_isNaN(d))
+        return uprv_getNaN();
+    if(uprv_isInfinite(d))
+        return uprv_getInfinity();
+
+    lowBits = *(uint32_t*) u_bottomNBytesOfDouble(&d, sizeof(uint32_t));
+    if( (d == 0.0 && (lowBits & SIGN)) || d < 0)
+        return ceil(d);
+    else
+        return floor(d);
+
+#else
+    return d >= 0 ? floor(d) : ceil(d);
+
+#endif
+}
+
+/**
+ * Return the largest positive number that can be represented by an integer
+ * type of arbitrary bit length.
+ */
+U_CAPI double U_EXPORT2
+uprv_maxMantissa(void)
+{
+    return pow(2.0, DBL_MANT_DIG + 1.0) - 1.0;
+}
+
+U_CAPI double U_EXPORT2
+uprv_log(double d)
+{
+    return log(d);
+}
+
+U_CAPI void * U_EXPORT2
+uprv_maximumPtr(void * base)
+{
+#if defined(OS400)
+    /*
+     * With the provided function we should never be out of range of a given segment
+     * (a traditional/typical segment that is).  Our segments have 5 bytes for the
+     * id and 3 bytes for the offset.  The key is that the casting takes care of
+     * only retrieving the offset portion minus x1000.  Hence, the smallest offset
+     * seen in a program is x001000 and when casted to an int would be 0.
+     * That's why we can only add 0xffefff.  Otherwise, we would exceed the segment.
+     *
+     * Currently, 16MB is the current addressing limitation on i5/OS if the activation is
+     * non-TERASPACE.  If it is TERASPACE it is 2GB - 4k(header information).
+     * This function determines the activation based on the pointer that is passed in and
+     * calculates the appropriate maximum available size for
+     * each pointer type (TERASPACE and non-TERASPACE)
+     *
+     * Unlike other operating systems, the pointer model isn't determined at
+     * compile time on i5/OS.
+     */
+    if ((base != NULL) && (_TESTPTR(base, _C_TERASPACE_CHECK))) {
+        /* if it is a TERASPACE pointer the max is 2GB - 4k */
+        return ((void *)(((char *)base)-((uint32_t)(base))+((uint32_t)0x7fffefff)));
+    }
+    /* otherwise 16MB since NULL ptr is not checkable or the ptr is not TERASPACE */
+    return ((void *)(((char *)base)-((uint32_t)(base))+((uint32_t)0xffefff)));
+
+#else
+    return U_MAX_PTR(base);
+#endif
+}
+
+/*---------------------------------------------------------------------------
+  Platform-specific Implementations
+  Try these, and if they don't work on your platform, then special case your
+  platform with new implementations.
+  ---------------------------------------------------------------------------*/
+
+/* Generic time zone layer -------------------------------------------------- */
+
+/* Time zone utilities */
+U_CAPI void U_EXPORT2
+uprv_tzset()
+{
+#ifdef U_TZSET
+    U_TZSET();
+#else
+    /* no initialization*/
+#endif
+}
+
+U_CAPI int32_t U_EXPORT2
+uprv_timezone()
+{
+#ifdef U_TIMEZONE
+    return U_TIMEZONE;
+#else
+    time_t t, t1, t2;
+    struct tm tmrec;
+    UBool dst_checked;
+    int32_t tdiff = 0;
+
+    time(&t);
+    uprv_memcpy( &tmrec, localtime(&t), sizeof(tmrec) );
+    dst_checked = (tmrec.tm_isdst != 0); /* daylight savings time is checked*/
+    t1 = mktime(&tmrec);                 /* local time in seconds*/
+    uprv_memcpy( &tmrec, gmtime(&t), sizeof(tmrec) );
+    t2 = mktime(&tmrec);                 /* GMT (or UTC) in seconds*/
+    tdiff = t2 - t1;
+    /* imitate NT behaviour, which returns same timezone offset to GMT for
+       winter and summer*/
+    if (dst_checked)
+        tdiff += 3600;
+    return tdiff;
+#endif
+}
+
+/* Note that U_TZNAME does *not* have to be tzname, but if it is,
+   some platforms need to have it declared here. */
+
+#if defined(U_TZNAME) && (defined(U_IRIX) || defined(U_DARWIN) || defined(U_CYGWIN))
+/* RS6000 and others reject char **tzname.  */
+extern U_IMPORT char *U_TZNAME[];
+#endif
+
+#if !UCONFIG_NO_FILE_IO && (defined(U_DARWIN) || defined(U_LINUX) || defined(U_BSD))
+/* These platforms are likely to use Olson timezone IDs. */
+#define CHECK_LOCALTIME_LINK 1
+#if defined(U_DARWIN)
+#include <tzfile.h>
+#define TZZONEINFO      (TZDIR "/")
+#else
+#define TZDEFAULT       "/etc/localtime"
+#define TZZONEINFO      "/usr/share/zoneinfo/"
+#endif
+#if U_HAVE_DIRENT_H
+#define TZFILE_SKIP     "posixrules" /* tz file to skip when searching. */
+#define SEARCH_TZFILE
+#include <dirent.h>  /* Needed to search through system timezone files */
+#endif
+static char gTimeZoneBuffer[PATH_MAX];
+static char *gTimeZoneBufferPtr = NULL;
+#endif
+
+#ifndef U_WINDOWS
+#define isNonDigit(ch) (ch < '0' || '9' < ch)
+static UBool isValidOlsonID(const char *id) {
+    int32_t idx = 0;
+
+    /* Determine if this is something like Iceland (Olson ID)
+    or AST4ADT (non-Olson ID) */
+    while (id[idx] && isNonDigit(id[idx]) && id[idx] != ',') {
+        idx++;
+    }
+
+    /* If we went through the whole string, then it might be okay.
+    The timezone is sometimes set to "CST-7CDT", "CST6CDT5,J129,J131/19:30",
+    "GRNLNDST3GRNLNDDT" or similar, so we cannot use it.
+    The rest of the time it could be an Olson ID. George */
+    return (UBool)(id[idx] == 0
+        || uprv_strcmp(id, "PST8PDT") == 0
+        || uprv_strcmp(id, "MST7MDT") == 0
+        || uprv_strcmp(id, "CST6CDT") == 0
+        || uprv_strcmp(id, "EST5EDT") == 0);
+}
+#endif
+
+#if defined(U_TZNAME) && !defined(U_WINDOWS)
+
+#define CONVERT_HOURS_TO_SECONDS(offset) (int32_t)(offset*3600)
+typedef struct OffsetZoneMapping {
+    int32_t offsetSeconds;
+    int32_t daylightType; /* 1=daylight in June, 2=daylight in December*/
+    const char *stdID;
+    const char *dstID;
+    const char *olsonID;
+} OffsetZoneMapping;
+
+/*
+This list tries to disambiguate a set of abbreviated timezone IDs and offsets
+and maps it to an Olson ID.
+Before adding anything to this list, take a look at
+icu/source/tools/tzcode/tz.alias
+Sometimes no daylight savings (0) is important to define due to aliases.
+This list can be tested with icu/source/test/compat/tzone.pl
+More values could be added to daylightType to increase precision.
+*/
+static const struct OffsetZoneMapping OFFSET_ZONE_MAPPINGS[] = {
+    {-45900, 2, "CHAST", "CHADT", "Pacific/Chatham"},
+    {-43200, 1, "PETT", "PETST", "Asia/Kamchatka"},
+    {-43200, 2, "NZST", "NZDT", "Pacific/Auckland"},
+    {-43200, 1, "ANAT", "ANAST", "Asia/Anadyr"},
+    {-39600, 1, "MAGT", "MAGST", "Asia/Magadan"},
+    {-37800, 2, "LHST", "LHST", "Australia/Lord_Howe"},
+    {-36000, 2, "EST", "EST", "Australia/Sydney"},
+    {-36000, 1, "SAKT", "SAKST", "Asia/Sakhalin"},
+    {-36000, 1, "VLAT", "VLAST", "Asia/Vladivostok"},
+    {-34200, 2, "CST", "CST", "Australia/South"},
+    {-32400, 1, "YAKT", "YAKST", "Asia/Yakutsk"},
+    {-32400, 1, "CHOT", "CHOST", "Asia/Choibalsan"},
+    {-31500, 2, "CWST", "CWST", "Australia/Eucla"},
+    {-28800, 1, "IRKT", "IRKST", "Asia/Irkutsk"},
+    {-28800, 1, "ULAT", "ULAST", "Asia/Ulaanbaatar"},
+    {-28800, 2, "WST", "WST", "Australia/West"},
+    {-25200, 1, "HOVT", "HOVST", "Asia/Hovd"},
+    {-25200, 1, "KRAT", "KRAST", "Asia/Krasnoyarsk"},
+    {-21600, 1, "NOVT", "NOVST", "Asia/Novosibirsk"},
+    {-21600, 1, "OMST", "OMSST", "Asia/Omsk"},
+    {-18000, 1, "YEKT", "YEKST", "Asia/Yekaterinburg"},
+    {-14400, 1, "SAMT", "SAMST", "Europe/Samara"},
+    {-14400, 1, "AMT", "AMST", "Asia/Yerevan"},
+    {-14400, 1, "AZT", "AZST", "Asia/Baku"},
+    {-10800, 1, "AST", "ADT", "Asia/Baghdad"},
+    {-10800, 1, "MSK", "MSD", "Europe/Moscow"},
+    {-10800, 1, "VOLT", "VOLST", "Europe/Volgograd"},
+    {-7200, 0, "EET", "CEST", "Africa/Tripoli"},
+    {-7200, 1, "EET", "EEST", "Europe/Athens"}, /* Conflicts with Africa/Cairo */
+    {-7200, 1, "IST", "IDT", "Asia/Jerusalem"},
+    {-3600, 0, "CET", "WEST", "Africa/Algiers"},
+    {-3600, 2, "WAT", "WAST", "Africa/Windhoek"},
+    {0, 1, "GMT", "IST", "Europe/Dublin"},
+    {0, 1, "GMT", "BST", "Europe/London"},
+    {0, 0, "WET", "WEST", "Africa/Casablanca"},
+    {0, 0, "WET", "WET", "Africa/El_Aaiun"},
+    {3600, 1, "AZOT", "AZOST", "Atlantic/Azores"},
+    {3600, 1, "EGT", "EGST", "America/Scoresbysund"},
+    {10800, 1, "PMST", "PMDT", "America/Miquelon"},
+    {10800, 2, "UYT", "UYST", "America/Montevideo"},
+    {10800, 1, "WGT", "WGST", "America/Godthab"},
+    {10800, 2, "BRT", "BRST", "Brazil/East"},
+    {12600, 1, "NST", "NDT", "America/St_Johns"},
+    {14400, 1, "AST", "ADT", "Canada/Atlantic"},
+    {14400, 2, "AMT", "AMST", "America/Cuiaba"},
+    {14400, 2, "CLT", "CLST", "Chile/Continental"},
+    {14400, 2, "FKT", "FKST", "Atlantic/Stanley"},
+    {14400, 2, "PYT", "PYST", "America/Asuncion"},
+    {18000, 1, "CST", "CDT", "America/Havana"},
+    {18000, 1, "EST", "EDT", "US/Eastern"}, /* Conflicts with America/Grand_Turk */
+    {21600, 2, "EAST", "EASST", "Chile/EasterIsland"},
+    {21600, 0, "CST", "MDT", "Canada/Saskatchewan"},
+    {21600, 0, "CST", "CDT", "America/Guatemala"},
+    {21600, 1, "CST", "CDT", "US/Central"}, /* Conflicts with Mexico/General */
+    {25200, 1, "MST", "MDT", "US/Mountain"}, /* Conflicts with Mexico/BajaSur */
+    {28800, 0, "PST", "PST", "Pacific/Pitcairn"},
+    {28800, 1, "PST", "PDT", "US/Pacific"}, /* Conflicts with Mexico/BajaNorte */
+    {32400, 1, "AKST", "AKDT", "US/Alaska"},
+    {36000, 1, "HAST", "HADT", "US/Aleutian"}
+};
+
+/*#define DEBUG_TZNAME*/
+
+static const char* remapShortTimeZone(const char *stdID, const char *dstID, int32_t daylightType, int32_t offset)
+{
+    int32_t idx;
+#ifdef DEBUG_TZNAME
+    fprintf(stderr, "TZ=%s std=%s dst=%s daylight=%d offset=%d\n", getenv("TZ"), stdID, dstID, daylightType, offset);
+#endif
+    for (idx = 0; idx < (int32_t)sizeof(OFFSET_ZONE_MAPPINGS)/sizeof(OFFSET_ZONE_MAPPINGS[0]); idx++)
+    {
+        if (offset == OFFSET_ZONE_MAPPINGS[idx].offsetSeconds
+            && daylightType == OFFSET_ZONE_MAPPINGS[idx].daylightType
+            && strcmp(OFFSET_ZONE_MAPPINGS[idx].stdID, stdID) == 0
+            && strcmp(OFFSET_ZONE_MAPPINGS[idx].dstID, dstID) == 0)
+        {
+            return OFFSET_ZONE_MAPPINGS[idx].olsonID;
+        }
+    }
+    return NULL;
+}
+#endif
+
+#ifdef SEARCH_TZFILE
+#define MAX_PATH_SIZE PATH_MAX /* Set the limit for the size of the path. */
+#define MAX_READ_SIZE 512
+
+typedef struct DefaultTZInfo {
+    char* defaultTZBuffer;
+    int64_t defaultTZFileSize;
+    FILE* defaultTZFilePtr;
+    UBool defaultTZstatus;
+    int32_t defaultTZPosition;
+} DefaultTZInfo;
+
+/*
+ * This method compares the two files given to see if they are a match.
+ * It is currently use to compare two TZ files.
+ */
+static UBool compareBinaryFiles(const char* defaultTZFileName, const char* TZFileName, DefaultTZInfo* tzInfo) {
+    FILE* file; 
+    int64_t sizeFile;
+    int64_t sizeFileLeft;
+    int32_t sizeFileRead;
+    int32_t sizeFileToRead;
+    char bufferFile[MAX_READ_SIZE];
+    UBool result = TRUE;
+
+    if (tzInfo->defaultTZFilePtr == NULL) {
+        tzInfo->defaultTZFilePtr = fopen(defaultTZFileName, "r");
+    }
+    file = fopen(TZFileName, "r");
+
+    tzInfo->defaultTZPosition = 0; /* reset position to begin search */
+
+    if (file != NULL && tzInfo->defaultTZFilePtr != NULL) {
+        /* First check that the file size are equal. */
+        if (tzInfo->defaultTZFileSize == 0) {
+            fseek(tzInfo->defaultTZFilePtr, 0, SEEK_END);
+            tzInfo->defaultTZFileSize = ftell(tzInfo->defaultTZFilePtr);
+        }
+        fseek(file, 0, SEEK_END);
+        sizeFile = ftell(file);
+        sizeFileLeft = sizeFile;
+
+        if (sizeFile != tzInfo->defaultTZFileSize) {
+            result = FALSE;
+        } else {
+            /* Store the data from the files in seperate buffers and
+             * compare each byte to determine equality.
+             */
+            if (tzInfo->defaultTZBuffer == NULL) {
+                rewind(tzInfo->defaultTZFilePtr);
+                tzInfo->defaultTZBuffer = (char*)uprv_malloc(sizeof(char) * tzInfo->defaultTZFileSize);
+                fread(tzInfo->defaultTZBuffer, 1, tzInfo->defaultTZFileSize, tzInfo->defaultTZFilePtr);
+            }
+            rewind(file);
+            while(sizeFileLeft > 0) {
+                uprv_memset(bufferFile, 0, MAX_READ_SIZE);
+                sizeFileToRead = sizeFileLeft < MAX_READ_SIZE ? sizeFileLeft : MAX_READ_SIZE;
+
+                sizeFileRead = fread(bufferFile, 1, sizeFileToRead, file);
+                if (memcmp(tzInfo->defaultTZBuffer + tzInfo->defaultTZPosition, bufferFile, sizeFileRead) != 0) {
+                    result = FALSE;
+                    break;
+                }
+                sizeFileLeft -= sizeFileRead;
+                tzInfo->defaultTZPosition += sizeFileRead;
+            }
+        }
+    } else {
+        result = FALSE;
+    }
+
+    if (file != NULL) {
+        fclose(file);
+    }
+
+    return result;
+}
+/*
+ * This method recursively traverses the directory given for a matching TZ file and returns the first match.
+ */
+/* dirent also lists two entries: "." and ".." that we can safely ignore. */
+#define SKIP1 "."
+#define SKIP2 ".."
+static char SEARCH_TZFILE_RESULT[MAX_PATH_SIZE] = "";
+static char* searchForTZFile(const char* path, DefaultTZInfo* tzInfo) {
+    char curpath[MAX_PATH_SIZE];
+    DIR* dirp = opendir(path);
+    DIR* subDirp = NULL;
+    struct dirent* dirEntry = NULL;
+
+    char* result = NULL;
+    if (dirp == NULL) {
+        return result;
+    }
+
+    /* Save the current path */
+    uprv_memset(curpath, 0, MAX_PATH_SIZE);
+    uprv_strcpy(curpath, path);
+
+    /* Check each entry in the directory. */
+    while((dirEntry = readdir(dirp)) != NULL) {
+        if (uprv_strcmp(dirEntry->d_name, SKIP1) != 0 && uprv_strcmp(dirEntry->d_name, SKIP2) != 0) {
+            /* Create a newpath with the new entry to test each entry in the directory. */
+            char newpath[MAX_PATH_SIZE];
+            uprv_strcpy(newpath, curpath);
+            uprv_strcat(newpath, dirEntry->d_name);
+
+            if ((subDirp = opendir(newpath)) != NULL) {
+                /* If this new path is a directory, make a recursive call with the newpath. */
+                closedir(subDirp);
+                uprv_strcat(newpath, "/");
+                result = searchForTZFile(newpath, tzInfo);
+            } else if (uprv_strcmp(TZFILE_SKIP, dirEntry->d_name) != 0) {
+                if(compareBinaryFiles(TZDEFAULT, newpath, tzInfo)) {
+                    uprv_strcpy(SEARCH_TZFILE_RESULT, newpath + (sizeof(TZZONEINFO) - 1));
+                    result = SEARCH_TZFILE_RESULT;
+                    /* Get out after the first one found. */
+                    break;
+                }
+            }
+        }
+    }
+    closedir(dirp);
+    return result;
+}
+#endif
+U_CAPI const char* U_EXPORT2
+uprv_tzname(int n)
+{
+    const char *tzid = NULL;
+#ifdef U_WINDOWS
+    tzid = uprv_detectWindowsTimeZone();
+
+    if (tzid != NULL) {
+        return tzid;
+    }
+#else
+
+/*#if defined(U_DARWIN)
+    int ret;
+
+    tzid = getenv("TZFILE");
+    if (tzid != NULL) {
+        return tzid;
+    }
+#endif*/
+
+/* This code can be temporarily disabled to test tzname resolution later on. */
+#ifndef DEBUG_TZNAME
+    tzid = getenv("TZ");
+    if (tzid != NULL && isValidOlsonID(tzid))
+    {
+        /* This might be a good Olson ID. */
+        if (uprv_strncmp(tzid, "posix/", 6) == 0
+            || uprv_strncmp(tzid, "right/", 6) == 0)
+        {
+            /* Remove the posix/ or right/ prefix. */
+            tzid += 6;
+        }
+        return tzid;
+    }
+    /* else U_TZNAME will give a better result. */
+#endif
+
+#if defined(CHECK_LOCALTIME_LINK)
+    /* Caller must handle threading issues */
+    if (gTimeZoneBufferPtr == NULL) {
+        /*
+        This is a trick to look at the name of the link to get the Olson ID
+        because the tzfile contents is underspecified.
+        This isn't guaranteed to work because it may not be a symlink.
+        */
+        int32_t ret = (int32_t)readlink(TZDEFAULT, gTimeZoneBuffer, sizeof(gTimeZoneBuffer));
+        if (0 < ret) {
+            int32_t tzZoneInfoLen = uprv_strlen(TZZONEINFO);
+            gTimeZoneBuffer[ret] = 0;
+            if (uprv_strncmp(gTimeZoneBuffer, TZZONEINFO, tzZoneInfoLen) == 0
+                && isValidOlsonID(gTimeZoneBuffer + tzZoneInfoLen))
+            {
+                return (gTimeZoneBufferPtr = gTimeZoneBuffer + tzZoneInfoLen);
+            }
+        } else {
+#if defined(SEARCH_TZFILE)
+            DefaultTZInfo* tzInfo = (DefaultTZInfo*)uprv_malloc(sizeof(DefaultTZInfo));
+            if (tzInfo != NULL) {
+                tzInfo->defaultTZBuffer = NULL;
+                tzInfo->defaultTZFileSize = 0;
+                tzInfo->defaultTZFilePtr = NULL;
+                tzInfo->defaultTZstatus = FALSE;
+                tzInfo->defaultTZPosition = 0;
+
+                gTimeZoneBufferPtr = searchForTZFile(TZZONEINFO, tzInfo);
+
+                /* Free previously allocated memory */
+                if (tzInfo->defaultTZBuffer != NULL) {
+                    uprv_free(tzInfo->defaultTZBuffer);
+                }
+                if (tzInfo->defaultTZFilePtr != NULL) {
+                    fclose(tzInfo->defaultTZFilePtr);
+                }
+                uprv_free(tzInfo);
+            }
+
+            if (gTimeZoneBufferPtr != NULL && isValidOlsonID(gTimeZoneBufferPtr)) {
+                return gTimeZoneBufferPtr;
+            }
+#endif
+        }
+    }
+    else {
+        return gTimeZoneBufferPtr;
+    }
+#endif
+#endif
+
+#ifdef U_TZNAME
+#ifdef U_WINDOWS
+    /* The return value is free'd in timezone.cpp on Windows because
+     * the other code path returns a pointer to a heap location. */
+    return uprv_strdup(U_TZNAME[n]);
+#else
+    /*
+    U_TZNAME is usually a non-unique abbreviation, which isn't normally usable.
+    So we remap the abbreviation to an olson ID.
+
+    Since Windows exposes a little more timezone information,
+    we normally don't use this code on Windows because
+    uprv_detectWindowsTimeZone should have already given the correct answer.
+    */
+    {
+        struct tm juneSol, decemberSol;
+        int daylightType;
+        static const time_t juneSolstice=1182478260; /*2007-06-21 18:11 UT*/
+        static const time_t decemberSolstice=1198332540; /*2007-12-22 06:09 UT*/
+
+        /* This probing will tell us when daylight savings occurs.  */
+        localtime_r(&juneSolstice, &juneSol);
+        localtime_r(&decemberSolstice, &decemberSol);
+        daylightType = ((decemberSol.tm_isdst > 0) << 1) | (juneSol.tm_isdst > 0);
+        tzid = remapShortTimeZone(U_TZNAME[0], U_TZNAME[1], daylightType, uprv_timezone());
+        if (tzid != NULL) {
+            return tzid;
+        }
+    }
+    return U_TZNAME[n];
+#endif
+#else
+    return "";
+#endif
+}
+
+/* Get and set the ICU data directory --------------------------------------- */
+
+static char *gDataDirectory = NULL;
+#if U_POSIX_LOCALE
+ static char *gCorrectedPOSIXLocale = NULL; /* Heap allocated */
+#endif
+
+static UBool U_CALLCONV putil_cleanup(void)
+{
+    if (gDataDirectory && *gDataDirectory) {
+        uprv_free(gDataDirectory);
+    }
+    gDataDirectory = NULL;
+#if U_POSIX_LOCALE
+    if (gCorrectedPOSIXLocale) {
+        uprv_free(gCorrectedPOSIXLocale);
+        gCorrectedPOSIXLocale = NULL;
+    }
+#endif
+    return TRUE;
+}
+
+/*
+ * Set the data directory.
+ *    Make a copy of the passed string, and set the global data dir to point to it.
+ *    TODO:  see bug #2849, regarding thread safety.
+ */
+U_CAPI void U_EXPORT2
+u_setDataDirectory(const char *directory) {
+    char *newDataDir;
+    int32_t length;
+
+    if(directory==NULL || *directory==0) {
+        /* A small optimization to prevent the malloc and copy when the
+        shared library is used, and this is a way to make sure that NULL
+        is never returned.
+        */
+        newDataDir = (char *)"";
+    }
+    else {
+        length=(int32_t)uprv_strlen(directory);
+        newDataDir = (char *)uprv_malloc(length + 2);
+        /* Exit out if newDataDir could not be created. */
+        if (newDataDir == NULL) {
+            return;
+        }
+        uprv_strcpy(newDataDir, directory);
+
+#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR)
+        {
+            char *p;
+            while(p = uprv_strchr(newDataDir, U_FILE_ALT_SEP_CHAR)) {
+                *p = U_FILE_SEP_CHAR;
+            }
+        }
+#endif
+    }
+
+    umtx_lock(NULL);
+    if (gDataDirectory && *gDataDirectory) {
+        uprv_free(gDataDirectory);
+    }
+    gDataDirectory = newDataDir;
+    ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
+    umtx_unlock(NULL);
+}
+
+U_CAPI UBool U_EXPORT2
+uprv_pathIsAbsolute(const char *path)
+{
+  if(!path || !*path) {
+    return FALSE;
+  }
+
+  if(*path == U_FILE_SEP_CHAR) {
+    return TRUE;
+  }
+
+#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR)
+  if(*path == U_FILE_ALT_SEP_CHAR) {
+    return TRUE;
+  }
+#endif
+
+#if defined(U_WINDOWS)
+  if( (((path[0] >= 'A') && (path[0] <= 'Z')) ||
+       ((path[0] >= 'a') && (path[0] <= 'z'))) &&
+      path[1] == ':' ) {
+    return TRUE;
+  }
+#endif
+
+  return FALSE;
+}
+
+U_CAPI const char * U_EXPORT2
+u_getDataDirectory(void) {
+    const char *path = NULL;
+#if defined(U_DARWIN) && TARGET_IPHONE_SIMULATOR
+    const char *simulator_root = NULL;
+    char datadir_path_buffer[PATH_MAX];
+#endif
+
+    /* if we have the directory, then return it immediately */
+    UMTX_CHECK(NULL, gDataDirectory, path);
+
+    if(path) {
+        return path;
+    }
+
+    /*
+    When ICU_NO_USER_DATA_OVERRIDE is defined, users aren't allowed to
+    override ICU's data with the ICU_DATA environment variable. This prevents
+    problems where multiple custom copies of ICU's specific version of data
+    are installed on a system. Either the application must define the data
+    directory with u_setDataDirectory, define ICU_DATA_DIR when compiling
+    ICU, set the data with udata_setCommonData or trust that all of the
+    required data is contained in ICU's data library that contains
+    the entry point defined by U_ICUDATA_ENTRY_POINT.
+
+    There may also be some platforms where environment variables
+    are not allowed.
+    */
+#   if !defined(ICU_NO_USER_DATA_OVERRIDE) && !UCONFIG_NO_FILE_IO
+    /* First try to get the environment variable */
+    path=getenv("ICU_DATA");
+#   endif
+
+    /* ICU_DATA_DIR may be set as a compile option */
+#   ifdef ICU_DATA_DIR
+    if(path==NULL || *path==0) {
+        path=ICU_DATA_DIR;
+#if defined(U_DARWIN) && TARGET_IPHONE_SIMULATOR
+        simulator_root=getenv("IPHONE_SIMULATOR_ROOT");
+        if (simulator_root != NULL) {
+            (void) strlcpy(datadir_path_buffer, simulator_root, PATH_MAX);
+            (void) strlcat(datadir_path_buffer, path, PATH_MAX);
+            path=datadir_path_buffer;
+        }
+#endif
+    }
+#   endif
+
+    if(path==NULL) {
+        /* It looks really bad, set it to something. */
+        path = "";
+    }
+
+    u_setDataDirectory(path);
+    return gDataDirectory;
+}
+
+
+
+
+
+/* Macintosh-specific locale information ------------------------------------ */
+#ifdef XP_MAC
+
+typedef struct {
+    int32_t script;
+    int32_t region;
+    int32_t lang;
+    int32_t date_region;
+    const char* posixID;
+} mac_lc_rec;
+
+/* Todo: This will be updated with a newer version from www.unicode.org web
+   page when it's available.*/
+#define MAC_LC_MAGIC_NUMBER -5
+#define MAC_LC_INIT_NUMBER -9
+
+static const mac_lc_rec mac_lc_recs[] = {
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 0, "en_US",
+    /* United States*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 1, "fr_FR",
+    /* France*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 2, "en_GB",
+    /* Great Britain*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 3, "de_DE",
+    /* Germany*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 4, "it_IT",
+    /* Italy*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 5, "nl_NL",
+    /* Metherlands*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 6, "fr_BE",
+    /* French for Belgium or Lxembourg*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 7, "sv_SE",
+    /* Sweden*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 9, "da_DK",
+    /* Denmark*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 10, "pt_PT",
+    /* Portugal*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 11, "fr_CA",
+    /* French Canada*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 13, "is_IS",
+    /* Israel*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 14, "ja_JP",
+    /* Japan*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 15, "en_AU",
+    /* Australia*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 16, "ar_AE",
+    /* the Arabic world (?)*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 17, "fi_FI",
+    /* Finland*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 18, "fr_CH",
+    /* French for Switzerland*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 19, "de_CH",
+    /* German for Switzerland*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 20, "el_GR",
+    /* Greece*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 21, "is_IS",
+    /* Iceland ===*/
+    /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 22, "",*/
+    /* Malta ===*/
+    /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 23, "",*/
+    /* Cyprus ===*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 24, "tr_TR",
+    /* Turkey ===*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 25, "sh_YU",
+    /* Croatian system for Yugoslavia*/
+    /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 33, "",*/
+    /* Hindi system for India*/
+    /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 34, "",*/
+    /* Pakistan*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 41, "lt_LT",
+    /* Lithuania*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 42, "pl_PL",
+    /* Poland*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 43, "hu_HU",
+    /* Hungary*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 44, "et_EE",
+    /* Estonia*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 45, "lv_LV",
+    /* Latvia*/
+    /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 46, "",*/
+    /* Lapland  [Ask Rich for the data. HS]*/
+    /*MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 47, "",*/
+    /* Faeroe Islands*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 48, "fa_IR",
+    /* Iran*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 49, "ru_RU",
+    /* Russia*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 50, "en_IE",
+    /* Ireland*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 51, "ko_KR",
+    /* Korea*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 52, "zh_CN",
+    /* People's Republic of China*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 53, "zh_TW",
+    /* Taiwan*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, 54, "th_TH",
+    /* Thailand*/
+
+    /* fallback is en_US*/
+    MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER, MAC_LC_MAGIC_NUMBER,
+    MAC_LC_MAGIC_NUMBER, "en_US"
+};
+
+#endif
+
+#if U_POSIX_LOCALE
+/* Return just the POSIX id, whatever happens to be in it */
+static const char *uprv_getPOSIXID(void)
+{
+    static const char* posixID = NULL;
+    if (posixID == 0) {
+        /*
+        * On Solaris two different calls to setlocale can result in
+        * different values. Only get this value once.
+        *
+        * We must check this first because an application can set this.
+        *
+        * LC_ALL can't be used because it's platform dependent. The LANG
+        * environment variable seems to affect LC_CTYPE variable by default.
+        * Here is what setlocale(LC_ALL, NULL) can return.
+        * HPUX can return 'C C C C C C C'
+        * Solaris can return /en_US/C/C/C/C/C on the second try.
+        * Linux can return LC_CTYPE=C;LC_NUMERIC=C;...
+        *
+        * The default codepage detection also needs to use LC_CTYPE.
+        *
+        * Do not call setlocale(LC_*, "")! Using an empty string instead
+        * of NULL, will modify the libc behavior.
+        */
+        posixID = setlocale(LC_CTYPE, NULL);
+        if ((posixID == 0)
+            || (uprv_strcmp("C", posixID) == 0)
+            || (uprv_strcmp("POSIX", posixID) == 0))
+        {
+            /* Maybe we got some garbage.  Try something more reasonable */
+            posixID = getenv("LC_ALL");
+            if (posixID == 0) {
+                posixID = getenv("LC_CTYPE");
+                if (posixID == 0) {
+                    posixID = getenv("LANG");
+                }
+            }
+        }
+
+        if ((posixID==0)
+            || (uprv_strcmp("C", posixID) == 0)
+            || (uprv_strcmp("POSIX", posixID) == 0))
+        {
+            /* Nothing worked.  Give it a nice POSIX default value. */
+            posixID = "en_US_POSIX";
+        }
+    }
+
+    return posixID;
+}
+#endif
+
+/* NOTE: The caller should handle thread safety */
+U_CAPI const char* U_EXPORT2
+uprv_getDefaultLocaleID()
+{
+#if U_POSIX_LOCALE
+/*
+  Note that:  (a '!' means the ID is improper somehow)
+     LC_ALL  ---->     default_loc          codepage
+--------------------------------------------------------
+     ab.CD             ab                   CD
+     ab@CD             ab__CD               -
+     ab@CD.EF          ab__CD               EF
+
+     ab_CD.EF@GH       ab_CD_GH             EF
+
+Some 'improper' ways to do the same as above:
+  !  ab_CD@GH.EF       ab_CD_GH             EF
+  !  ab_CD.EF@GH.IJ    ab_CD_GH             EF
+  !  ab_CD@ZZ.EF@GH.IJ ab_CD_GH             EF
+
+     _CD@GH            _CD_GH               -
+     _CD.EF@GH         _CD_GH               EF
+
+The variant cannot have dots in it.
+The 'rightmost' variant (@xxx) wins.
+The leftmost codepage (.xxx) wins.
+*/
+    char *correctedPOSIXLocale = 0;
+    const char* posixID = uprv_getPOSIXID();
+    const char *p;
+    const char *q;
+    int32_t len;
+
+    /* Format: (no spaces)
+    ll [ _CC ] [ . MM ] [ @ VV]
+
+      l = lang, C = ctry, M = charmap, V = variant
+    */
+
+    if (gCorrectedPOSIXLocale != NULL) {
+        return gCorrectedPOSIXLocale;
+    }
+
+    if ((p = uprv_strchr(posixID, '.')) != NULL) {
+        /* assume new locale can't be larger than old one? */
+        correctedPOSIXLocale = uprv_malloc(uprv_strlen(posixID)+1);
+        /* Exit on memory allocation error. */
+        if (correctedPOSIXLocale == NULL) {
+            return NULL;
+        }
+        uprv_strncpy(correctedPOSIXLocale, posixID, p-posixID);
+        correctedPOSIXLocale[p-posixID] = 0;
+
+        /* do not copy after the @ */
+        if ((p = uprv_strchr(correctedPOSIXLocale, '@')) != NULL) {
+            correctedPOSIXLocale[p-correctedPOSIXLocale] = 0;
+        }
+    }
+
+    /* Note that we scan the *uncorrected* ID. */
+    if ((p = uprv_strrchr(posixID, '@')) != NULL) {
+        if (correctedPOSIXLocale == NULL) {
+            correctedPOSIXLocale = uprv_malloc(uprv_strlen(posixID)+1);
+            /* Exit on memory allocation error. */
+            if (correctedPOSIXLocale == NULL) {
+                return NULL;
+            }
+            uprv_strncpy(correctedPOSIXLocale, posixID, p-posixID);
+            correctedPOSIXLocale[p-posixID] = 0;
+        }
+        p++;
+
+        /* Take care of any special cases here.. */
+        if (!uprv_strcmp(p, "nynorsk")) {
+            p = "NY";
+            /* Don't worry about no__NY. In practice, it won't appear. */
+        }
+
+        if (uprv_strchr(correctedPOSIXLocale,'_') == NULL) {
+            uprv_strcat(correctedPOSIXLocale, "__"); /* aa@b -> aa__b */
+        }
+        else {
+            uprv_strcat(correctedPOSIXLocale, "_"); /* aa_CC@b -> aa_CC_b */
+        }
+
+        if ((q = uprv_strchr(p, '.')) != NULL) {
+            /* How big will the resulting string be? */
+            len = (int32_t)(uprv_strlen(correctedPOSIXLocale) + (q-p));
+            uprv_strncat(correctedPOSIXLocale, p, q-p);
+            correctedPOSIXLocale[len] = 0;
+        }
+        else {
+            /* Anything following the @ sign */
+            uprv_strcat(correctedPOSIXLocale, p);
+        }
+
+        /* Should there be a map from 'no@nynorsk' -> no_NO_NY here?
+         * How about 'russian' -> 'ru'?
+         * Many of the other locales using ISO codes will be handled by the
+         * canonicalization functions in uloc_getDefault.
+         */
+    }
+
+    /* Was a correction made? */
+    if (correctedPOSIXLocale != NULL) {
+        posixID = correctedPOSIXLocale;
+    }
+    else {
+        /* copy it, just in case the original pointer goes away.  See j2395 */
+        correctedPOSIXLocale = (char *)uprv_malloc(uprv_strlen(posixID) + 1);
+        /* Exit on memory allocation error. */
+        if (correctedPOSIXLocale == NULL) {
+            return NULL;
+        }
+        posixID = uprv_strcpy(correctedPOSIXLocale, posixID);
+    }
+
+    if (gCorrectedPOSIXLocale == NULL) {
+        gCorrectedPOSIXLocale = correctedPOSIXLocale;
+        ucln_common_registerCleanup(UCLN_COMMON_PUTIL, putil_cleanup);
+        correctedPOSIXLocale = NULL;
+    }
+
+    if (correctedPOSIXLocale != NULL) {  /* Was already set - clean up. */
+        uprv_free(correctedPOSIXLocale);
+    }
+
+    return posixID;
+
+#elif defined(U_WINDOWS)
+    UErrorCode status = U_ZERO_ERROR;
+    LCID id = GetThreadLocale();
+    const char* locID = uprv_convertToPosix(id, &status);
+
+    if (U_FAILURE(status)) {
+        locID = "en_US";
+    }
+    return locID;
+
+#elif defined(XP_MAC)
+    int32_t script = MAC_LC_INIT_NUMBER;
+    /* = IntlScript(); or GetScriptManagerVariable(smSysScript);*/
+    int32_t region = MAC_LC_INIT_NUMBER;
+    /* = GetScriptManagerVariable(smRegionCode);*/
+    int32_t lang = MAC_LC_INIT_NUMBER;
+    /* = GetScriptManagerVariable(smScriptLang);*/
+    int32_t date_region = MAC_LC_INIT_NUMBER;
+    const char* posixID = 0;
+    int32_t count = sizeof(mac_lc_recs) / sizeof(mac_lc_rec);
+    int32_t i;
+    Intl1Hndl ih;
+
+    ih = (Intl1Hndl) GetIntlResource(1);
+    if (ih)
+        date_region = ((uint16_t)(*ih)->intl1Vers) >> 8;
+
+    for (i = 0; i < count; i++) {
+        if (   ((mac_lc_recs[i].script == MAC_LC_MAGIC_NUMBER)
+             || (mac_lc_recs[i].script == script))
+            && ((mac_lc_recs[i].region == MAC_LC_MAGIC_NUMBER)
+             || (mac_lc_recs[i].region == region))
+            && ((mac_lc_recs[i].lang == MAC_LC_MAGIC_NUMBER)
+             || (mac_lc_recs[i].lang == lang))
+            && ((mac_lc_recs[i].date_region == MAC_LC_MAGIC_NUMBER)
+             || (mac_lc_recs[i].date_region == date_region))
+            )
+        {
+            posixID = mac_lc_recs[i].posixID;
+            break;
+        }
+    }
+
+    return posixID;
+
+#elif defined(OS400)
+    /* locales are process scoped and are by definition thread safe */
+    static char correctedLocale[64];
+    const  char *localeID = getenv("LC_ALL");
+           char *p;
+
+    if (localeID == NULL)
+        localeID = getenv("LANG");
+    if (localeID == NULL)
+        localeID = setlocale(LC_ALL, NULL);
+    /* Make sure we have something... */
+    if (localeID == NULL)
+        return "en_US_POSIX";
+
+    /* Extract the locale name from the path. */
+    if((p = uprv_strrchr(localeID, '/')) != NULL)
+    {
+        /* Increment p to start of locale name. */
+        p++;
+        localeID = p;
+    }
+
+    /* Copy to work location. */
+    uprv_strcpy(correctedLocale, localeID);
+
+    /* Strip off the '.locale' extension. */
+    if((p = uprv_strchr(correctedLocale, '.')) != NULL) {
+        *p = 0;
+    }
+
+    /* Upper case the locale name. */
+    T_CString_toUpperCase(correctedLocale);
+
+    /* See if we are using the POSIX locale.  Any of the
+    * following are equivalent and use the same QLGPGCMA
+    * (POSIX) locale.
+    * QLGPGCMA2 means UCS2
+    * QLGPGCMA_4 means UTF-32
+    * QLGPGCMA_8 means UTF-8
+    */
+    if ((uprv_strcmp("C", correctedLocale) == 0) ||
+        (uprv_strcmp("POSIX", correctedLocale) == 0) ||
+        (uprv_strncmp("QLGPGCMA", correctedLocale, 8) == 0))
+    {
+        uprv_strcpy(correctedLocale, "en_US_POSIX");
+    }
+    else
+    {
+        int16_t LocaleLen;
+
+        /* Lower case the lang portion. */
+        for(p = correctedLocale; *p != 0 && *p != '_'; p++)
+        {
+            *p = uprv_tolower(*p);
+        }
+
+        /* Adjust for Euro.  After '_E' add 'URO'. */
+        LocaleLen = uprv_strlen(correctedLocale);
+        if (correctedLocale[LocaleLen - 2] == '_' &&
+            correctedLocale[LocaleLen - 1] == 'E')
+        {
+            uprv_strcat(correctedLocale, "URO");
+        }
+
+        /* If using Lotus-based locale then convert to
+         * equivalent non Lotus.
+         */
+        else if (correctedLocale[LocaleLen - 2] == '_' &&
+            correctedLocale[LocaleLen - 1] == 'L')
+        {
+            correctedLocale[LocaleLen - 2] = 0;
+        }
+
+        /* There are separate simplified and traditional
+         * locales called zh_HK_S and zh_HK_T.
+         */
+        else if (uprv_strncmp(correctedLocale, "zh_HK", 5) == 0)
+        {
+            uprv_strcpy(correctedLocale, "zh_HK");
+        }
+
+        /* A special zh_CN_GBK locale...
+        */
+        else if (uprv_strcmp(correctedLocale, "zh_CN_GBK") == 0)
+        {
+            uprv_strcpy(correctedLocale, "zh_CN");
+        }
+
+    }
+
+    return correctedLocale;
+#endif
+
+}
+
+#if !U_CHARSET_IS_UTF8
+#if U_POSIX_LOCALE
+/*
+Due to various platform differences, one platform may specify a charset,
+when they really mean a different charset. Remap the names so that they are
+compatible with ICU. Only conflicting/ambiguous aliases should be resolved
+here. Before adding anything to this function, please consider adding unique
+names to the ICU alias table in the data directory.
+*/
+static const char*
+remapPlatformDependentCodepage(const char *locale, const char *name) {
+    if (locale != NULL && *locale == 0) {
+        /* Make sure that an empty locale is handled the same way. */
+        locale = NULL;
+    }
+    if (name == NULL) {
+        return NULL;
+    }
+#if defined(U_AIX)
+    if (uprv_strcmp(name, "IBM-943") == 0) {
+        /* Use the ASCII compatible ibm-943 */
+        name = "Shift-JIS";
+    }
+    else if (uprv_strcmp(name, "IBM-1252") == 0) {
+        /* Use the windows-1252 that contains the Euro */
+        name = "IBM-5348";
+    }
+#elif defined(U_SOLARIS)
+    if (locale != NULL && uprv_strcmp(name, "EUC") == 0) {
+        /* Solaris underspecifies the "EUC" name. */
+        if (uprv_strcmp(locale, "zh_CN") == 0) {
+            name = "EUC-CN";
+        }
+        else if (uprv_strcmp(locale, "zh_TW") == 0) {
+            name = "EUC-TW";
+        }
+        else if (uprv_strcmp(locale, "ko_KR") == 0) {
+            name = "EUC-KR";
+        }
+    }
+    else if (uprv_strcmp(name, "eucJP") == 0) {
+        /*
+        ibm-954 is the best match.
+        ibm-33722 is the default for eucJP (similar to Windows).
+        */
+        name = "eucjis";
+    }
+    else if (uprv_strcmp(name, "646") == 0) {
+        /*
+         * The default codepage given by Solaris is 646 but the C library routines treat it as if it was
+         * ISO-8859-1 instead of US-ASCII(646).
+         */
+        name = "ISO-8859-1";
+    }
+#elif defined(U_DARWIN)
+    if (locale == NULL && *name == 0) {
+        /*
+        No locale was specified, and an empty name was passed in.
+        This usually indicates that nl_langinfo didn't return valid information.
+        Mac OS X uses UTF-8 by default (especially the locale data and console).
+        */
+        name = "UTF-8";
+    }
+    else if (uprv_strcmp(name, "CP949") == 0) {
+        /* Remap CP949 to a similar codepage to avoid issues with backslash and won symbol. */
+        name = "EUC-KR";
+    }
+    else if (locale != NULL && uprv_strcmp(locale, "en_US_POSIX") != 0 && uprv_strcmp(name, "US-ASCII") == 0) {
+        /*
+         * For non C/POSIX locale, default the code page to UTF-8 instead of US-ASCII.
+         */
+        name = "UTF-8";
+    }
+#elif defined(U_BSD)
+    if (uprv_strcmp(name, "CP949") == 0) {
+        /* Remap CP949 to a similar codepage to avoid issues with backslash and won symbol. */
+        name = "EUC-KR";
+    }
+#elif defined(U_HPUX)
+    if (locale != NULL && uprv_strcmp(locale, "zh_HK") == 0 && uprv_strcmp(name, "big5") == 0) {
+        /* HP decided to extend big5 as hkbig5 even though it's not compatible :-( */
+        /* zh_TW.big5 is not the same charset as zh_HK.big5! */
+        name = "hkbig5";
+    }
+    else if (uprv_strcmp(name, "eucJP") == 0) {
+        /*
+        ibm-1350 is the best match, but unavailable.
+        ibm-954 is mostly a superset of ibm-1350.
+        ibm-33722 is the default for eucJP (similar to Windows).
+        */
+        name = "eucjis";
+    }
+#elif defined(U_LINUX)
+    if (locale != NULL && uprv_strcmp(name, "euc") == 0) {
+        /* Linux underspecifies the "EUC" name. */
+        if (uprv_strcmp(locale, "korean") == 0) {
+            name = "EUC-KR";
+        }
+        else if (uprv_strcmp(locale, "japanese") == 0) {
+            /* See comment below about eucJP */
+            name = "eucjis";
+        }
+    }
+    else if (uprv_strcmp(name, "eucjp") == 0) {
+        /*
+        ibm-1350 is the best match, but unavailable.
+        ibm-954 is mostly a superset of ibm-1350.
+        ibm-33722 is the default for eucJP (similar to Windows).
+        */
+        name = "eucjis";
+    }
+    else if (locale != NULL && uprv_strcmp(locale, "en_US_POSIX") != 0 &&
+            (uprv_strcmp(name, "ANSI_X3.4-1968") == 0 || uprv_strcmp(name, "US-ASCII") == 0)) {
+        /*
+         * For non C/POSIX locale, default the code page to UTF-8 instead of US-ASCII.
+         */
+        name = "UTF-8";
+    }
+#endif
+    /* return NULL when "" is passed in */
+    if (*name == 0) {
+        name = NULL;
+    }
+    return name;
+}
+
+static const char*
+getCodepageFromPOSIXID(const char *localeName, char * buffer, int32_t buffCapacity)
+{
+    char localeBuf[100];
+    const char *name = NULL;
+    char *variant = NULL;
+
+    if (localeName != NULL && (name = (uprv_strchr(localeName, '.'))) != NULL) {
+        size_t localeCapacity = uprv_min(sizeof(localeBuf), (name-localeName)+1);
+        uprv_strncpy(localeBuf, localeName, localeCapacity);
+        localeBuf[localeCapacity-1] = 0; /* ensure NULL termination */
+        name = uprv_strncpy(buffer, name+1, buffCapacity);
+        buffer[buffCapacity-1] = 0; /* ensure NULL termination */
+        if ((variant = (uprv_strchr(name, '@'))) != NULL) {
+            *variant = 0;
+        }
+        name = remapPlatformDependentCodepage(localeBuf, name);
+    }
+    return name;
+}
+#endif
+
+static const char*
+int_getDefaultCodepage()
+{
+#if defined(OS400)
+    uint32_t ccsid = 37; /* Default to ibm-37 */
+    static char codepage[64];
+    Qwc_JOBI0400_t jobinfo;
+    Qus_EC_t error = { sizeof(Qus_EC_t) }; /* SPI error code */
+
+    EPT_CALL(QUSRJOBI)(&jobinfo, sizeof(jobinfo), "JOBI0400",
+        "*                         ", "                ", &error);
+
+    if (error.Bytes_Available == 0) {
+        if (jobinfo.Coded_Char_Set_ID != 0xFFFF) {
+            ccsid = (uint32_t)jobinfo.Coded_Char_Set_ID;
+        }
+        else if (jobinfo.Default_Coded_Char_Set_Id != 0xFFFF) {
+            ccsid = (uint32_t)jobinfo.Default_Coded_Char_Set_Id;
+        }
+        /* else use the default */
+    }
+    sprintf(codepage,"ibm-%d", ccsid);
+    return codepage;
+
+#elif defined(OS390)
+    static char codepage[64];
+
+    strncpy(codepage, nl_langinfo(CODESET),63-strlen(UCNV_SWAP_LFNL_OPTION_STRING));
+    strcat(codepage,UCNV_SWAP_LFNL_OPTION_STRING);
+    codepage[63] = 0; /* NULL terminate */
+
+    return codepage;
+
+#elif defined(XP_MAC)
+    return "macintosh"; /* TODO: Macintosh Roman. There must be a better way. fixme! */
+
+#elif defined(U_WINDOWS)
+    static char codepage[64];
+    sprintf(codepage, "windows-%d", GetACP());
+    return codepage;
+
+#elif U_POSIX_LOCALE
+    static char codesetName[100];
+    const char *localeName = NULL;
+    const char *name = NULL;
+
+    uprv_memset(codesetName, 0, sizeof(codesetName));
+
+    /* Use setlocale in a nice way, and then check some environment variables.
+       Maybe the application used setlocale already.
+    */
+    localeName = uprv_getPOSIXID();
+    name = getCodepageFromPOSIXID(localeName, codesetName, sizeof(codesetName));
+    if (name) {
+        /* if we can find the codeset name from setlocale, return that. */
+        return name;
+    }
+    /* else "C" was probably returned. That's underspecified. */
+
+#if U_HAVE_NL_LANGINFO_CODESET
+    if (*codesetName) {
+        uprv_memset(codesetName, 0, sizeof(codesetName));
+    }
+    /* When available, check nl_langinfo because it usually gives more
+       useful names. It depends on LC_CTYPE and not LANG or LC_ALL.
+       nl_langinfo may use the same buffer as setlocale. */
+    {
+        const char *codeset = nl_langinfo(U_NL_LANGINFO_CODESET);
+#if defined(U_DARWIN) || defined(U_LINUX)
+        /*
+         * On Linux and MacOSX, ensure that default codepage for non C/POSIX locale is UTF-8
+         * instead of ASCII.
+         */
+        if (uprv_strcmp(localeName, "en_US_POSIX") != 0) {
+            codeset = remapPlatformDependentCodepage(localeName, codeset);
+        } else
+#endif
+        {
+            codeset = remapPlatformDependentCodepage(NULL, codeset);
+        }
+
+        if (codeset != NULL) {
+            uprv_strncpy(codesetName, codeset, sizeof(codesetName));
+            codesetName[sizeof(codesetName)-1] = 0;
+            return codesetName;
+        }
+    }
+#endif
+
+    if (*codesetName == 0)
+    {
+        /* Everything failed. Return US ASCII (ISO 646). */
+        (void)uprv_strcpy(codesetName, "US-ASCII");
+    }
+    return codesetName;
+#else
+    return "US-ASCII";
+#endif
+}
+
+
+U_CAPI const char*  U_EXPORT2
+uprv_getDefaultCodepage()
+{
+    static char const  *name = NULL;
+    umtx_lock(NULL);
+    if (name == NULL) {
+        name = int_getDefaultCodepage();
+    }
+    umtx_unlock(NULL);
+    return name;
+}
+#endif  /* !U_CHARSET_IS_UTF8 */
+
+
+/* end of platform-specific implementation -------------- */
+
+/* version handling --------------------------------------------------------- */
+
+U_CAPI void U_EXPORT2
+u_versionFromString(UVersionInfo versionArray, const char *versionString) {
+    char *end;
+    uint16_t part=0;
+
+    if(versionArray==NULL) {
+        return;
+    }
+
+    if(versionString!=NULL) {
+        for(;;) {
+            versionArray[part]=(uint8_t)uprv_strtoul(versionString, &end, 10);
+            if(end==versionString || ++part==U_MAX_VERSION_LENGTH || *end!=U_VERSION_DELIMITER) {
+                break;
+            }
+            versionString=end+1;
+        }
+    }
+
+    while(part<U_MAX_VERSION_LENGTH) {
+        versionArray[part++]=0;
+    }
+}
+
+U_CAPI void U_EXPORT2
+u_versionFromUString(UVersionInfo versionArray, const UChar *versionString) {
+    if(versionArray!=NULL && versionString!=NULL) {
+        char versionChars[U_MAX_VERSION_STRING_LENGTH+1];
+        int32_t len = u_strlen(versionString);
+        if(len>U_MAX_VERSION_STRING_LENGTH) {
+            len = U_MAX_VERSION_STRING_LENGTH;
+        }
+        u_UCharsToChars(versionString, versionChars, len);
+        versionChars[len]=0;
+        u_versionFromString(versionArray, versionChars);
+    }
+}
+
+U_CAPI void U_EXPORT2
+u_versionToString(UVersionInfo versionArray, char *versionString) {
+    uint16_t count, part;
+    uint8_t field;
+
+    if(versionString==NULL) {
+        return;
+    }
+
+    if(versionArray==NULL) {
+        versionString[0]=0;
+        return;
+    }
+
+    /* count how many fields need to be written */
+    for(count=4; count>0 && versionArray[count-1]==0; --count) {
+    }
+
+    if(count <= 1) {
+        count = 2;
+    }
+
+    /* write the first part */
+    /* write the decimal field value */
+    field=versionArray[0];
+    if(field>=100) {
+        *versionString++=(char)('0'+field/100);
+        field%=100;
+    }
+    if(field>=10) {
+        *versionString++=(char)('0'+field/10);
+        field%=10;
+    }
+    *versionString++=(char)('0'+field);
+
+    /* write the following parts */
+    for(part=1; part<count; ++part) {
+        /* write a dot first */
+        *versionString++=U_VERSION_DELIMITER;
+
+        /* write the decimal field value */
+        field=versionArray[part];
+        if(field>=100) {
+            *versionString++=(char)('0'+field/100);
+            field%=100;
+        }
+        if(field>=10) {
+            *versionString++=(char)('0'+field/10);
+            field%=10;
+        }
+        *versionString++=(char)('0'+field);
+    }
+
+    /* NUL-terminate */
+    *versionString=0;
+}
+
+U_CAPI void U_EXPORT2
+u_getVersion(UVersionInfo versionArray) {
+    u_versionFromString(versionArray, U_ICU_VERSION);
+}
+
+/**
+ * icucfg.h dependent code 
+ */
+
+#if U_ENABLE_DYLOAD
+ 
+#if defined(U_CHECK_DYLOAD)
+
+#if defined(HAVE_DLOPEN) 
+
+#ifdef HAVE_DLFCN_H
+#ifdef __MVS__
+#ifndef __SUSV3
+#define __SUSV3 1
+#endif
+#endif
+#include <dlfcn.h>
+#endif
+
+U_INTERNAL void * U_EXPORT2
+uprv_dl_open(const char *libName, UErrorCode *status) {
+    void *ret = NULL;
+    if(U_FAILURE(*status)) return ret;
+    ret =  dlopen(libName, RTLD_NOW|RTLD_GLOBAL);
+    if(ret==NULL) {
+        perror("dlopen");
+        *status = U_MISSING_RESOURCE_ERROR;
+        /* TODO: read errno and translate. */
+    }
+    return ret;
+}
+
+U_INTERNAL void U_EXPORT2
+uprv_dl_close(void *lib, UErrorCode *status) {
+    if(U_FAILURE(*status)) return;
+    dlclose(lib);
+    /* TODO: translate errno? */
+}
+
+U_INTERNAL void* U_EXPORT2
+uprv_dl_sym(void *lib, const char* sym, UErrorCode *status) {
+    void *ret = NULL;
+    if(U_FAILURE(*status)) return ret;
+    ret = dlsym(lib, sym);
+    if(ret == NULL) {
+        *status = U_MISSING_RESOURCE_ERROR;
+        /* TODO: translate errno? */
+    }
+    return ret;
+}
+
+#else
+
+/* null (nonexistent) implementation. */
+
+U_INTERNAL void * U_EXPORT2
+uprv_dl_open(const char *libName, UErrorCode *status) {
+    if(U_FAILURE(*status)) return NULL;
+    *status = U_UNSUPPORTED_ERROR;
+    return NULL;
+}
+
+U_INTERNAL void U_EXPORT2
+uprv_dl_close(void *lib, UErrorCode *status) {
+    if(U_FAILURE(*status)) return;
+    *status = U_UNSUPPORTED_ERROR;
+    return;
+}
+
+
+U_INTERNAL void* U_EXPORT2
+uprv_dl_sym(void *lib, const char* sym, UErrorCode *status) {
+    if(U_FAILURE(*status)) return NULL;
+    *status = U_UNSUPPORTED_ERROR;
+    return NULL;
+}
+
+
+
+#endif
+
+#elif defined U_WINDOWS
+
+U_INTERNAL void * U_EXPORT2
+uprv_dl_open(const char *libName, UErrorCode *status) {
+   	HMODULE lib = NULL;
+
+	if(U_FAILURE(*status)) return NULL;
+    
+	lib = LoadLibrary(libName);
+
+	if(lib==NULL) {
+		*status = U_MISSING_RESOURCE_ERROR;
+	}
+
+    return (void*)lib;
+}
+
+U_INTERNAL void U_EXPORT2
+uprv_dl_close(void *lib, UErrorCode *status) {
+	HMODULE handle = (HMODULE)lib;
+    if(U_FAILURE(*status)) return;
+    
+	FreeLibrary(handle);
+
+    return;
+}
+
+
+U_INTERNAL void* U_EXPORT2
+uprv_dl_sym(void *lib, const char* sym, UErrorCode *status) {
+	HMODULE handle = (HMODULE)lib;
+	void * addr = NULL;
+
+	if(U_FAILURE(*status) || lib==NULL) return NULL;
+   
+	addr = GetProcAddress(handle, sym);
+
+	if(addr==NULL) {
+		DWORD lastError = GetLastError();
+		if(lastError == ERROR_PROC_NOT_FOUND) {
+			*status = U_MISSING_RESOURCE_ERROR;
+		} else {
+			*status = U_UNSUPPORTED_ERROR; /* other unknown error. */
+		}
+	}
+
+    return addr;
+}
+
+
+#else
+
+/* No dynamic loading set. */
+
+U_INTERNAL void * U_EXPORT2
+uprv_dl_open(const char *libName, UErrorCode *status) {
+    if(U_FAILURE(*status)) return NULL;
+    *status = U_UNSUPPORTED_ERROR;
+    return NULL;
+}
+
+U_INTERNAL void U_EXPORT2
+uprv_dl_close(void *lib, UErrorCode *status) {
+    if(U_FAILURE(*status)) return;
+    *status = U_UNSUPPORTED_ERROR;
+    return;
+}
+
+
+U_INTERNAL void* U_EXPORT2
+uprv_dl_sym(void *lib, const char* sym, UErrorCode *status) {
+    if(U_FAILURE(*status)) return NULL;
+    *status = U_UNSUPPORTED_ERROR;
+    return NULL;
+}
+
+
+#endif
+
+#endif /* U_ENABLE_DYLOAD */
+
+/*
+ * Hey, Emacs, please set the following:
+ *
+ * Local Variables:
+ * indent-tabs-mode: nil
+ * End:
+ *
+ */
diff --git a/icu/source/common/putilimp.h b/icu/source/common/putilimp.h
new file mode 100644
index 0000000..1c33ca8
--- /dev/null
+++ b/icu/source/common/putilimp.h
@@ -0,0 +1,300 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1997-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+*  FILE NAME : putilimp.h
+*
+*   Date        Name        Description
+*   10/17/04    grhoten     Move internal functions from putil.h to this file.
+******************************************************************************
+*/
+
+#ifndef PUTILIMP_H
+#define PUTILIMP_H
+
+#include "unicode/utypes.h"
+#include "unicode/putil.h"
+
+/*==========================================================================*/
+/* Platform utilities                                                       */
+/*==========================================================================*/
+
+/**
+ * Platform utilities isolates the platform dependencies of the
+ * libarary.  For each platform which this code is ported to, these
+ * functions may have to be re-implemented.
+ */
+
+/**
+ * Floating point utility to determine if a double is Not a Number (NaN).
+ * @internal
+ */
+U_INTERNAL UBool   U_EXPORT2 uprv_isNaN(double d);
+/**
+ * Floating point utility to determine if a double has an infinite value.
+ * @internal
+ */
+U_INTERNAL UBool   U_EXPORT2 uprv_isInfinite(double d);
+/**
+ * Floating point utility to determine if a double has a positive infinite value.
+ * @internal
+ */
+U_INTERNAL UBool   U_EXPORT2 uprv_isPositiveInfinity(double d);
+/**
+ * Floating point utility to determine if a double has a negative infinite value.
+ * @internal
+ */
+U_INTERNAL UBool   U_EXPORT2 uprv_isNegativeInfinity(double d);
+/**
+ * Floating point utility that returns a Not a Number (NaN) value.
+ * @internal
+ */
+U_INTERNAL double  U_EXPORT2 uprv_getNaN(void);
+/**
+ * Floating point utility that returns an infinite value.
+ * @internal
+ */
+U_INTERNAL double  U_EXPORT2 uprv_getInfinity(void);
+
+/**
+ * Floating point utility to truncate a double.
+ * @internal
+ */
+U_INTERNAL double  U_EXPORT2 uprv_trunc(double d);
+/**
+ * Floating point utility to calculate the floor of a double.
+ * @internal
+ */
+U_INTERNAL double  U_EXPORT2 uprv_floor(double d);
+/**
+ * Floating point utility to calculate the ceiling of a double.
+ * @internal
+ */
+U_INTERNAL double  U_EXPORT2 uprv_ceil(double d);
+/**
+ * Floating point utility to calculate the absolute value of a double.
+ * @internal
+ */
+U_INTERNAL double  U_EXPORT2 uprv_fabs(double d);
+/**
+ * Floating point utility to calculate the fractional and integer parts of a double.
+ * @internal
+ */
+U_INTERNAL double  U_EXPORT2 uprv_modf(double d, double* pinteger);
+/**
+ * Floating point utility to calculate the remainder of a double divided by another double.
+ * @internal
+ */
+U_INTERNAL double  U_EXPORT2 uprv_fmod(double d, double y);
+/**
+ * Floating point utility to calculate d to the power of exponent (d^exponent).
+ * @internal
+ */
+U_INTERNAL double  U_EXPORT2 uprv_pow(double d, double exponent);
+/**
+ * Floating point utility to calculate 10 to the power of exponent (10^exponent).
+ * @internal
+ */
+U_INTERNAL double  U_EXPORT2 uprv_pow10(int32_t exponent);
+/**
+ * Floating point utility to calculate the maximum value of two doubles.
+ * @internal
+ */
+U_INTERNAL double  U_EXPORT2 uprv_fmax(double d, double y);
+/**
+ * Floating point utility to calculate the minimum value of two doubles.
+ * @internal
+ */
+U_INTERNAL double  U_EXPORT2 uprv_fmin(double d, double y);
+/**
+ * Private utility to calculate the maximum value of two integers.
+ * @internal
+ */
+U_INTERNAL int32_t U_EXPORT2 uprv_max(int32_t d, int32_t y);
+/**
+ * Private utility to calculate the minimum value of two integers.
+ * @internal
+ */
+U_INTERNAL int32_t U_EXPORT2 uprv_min(int32_t d, int32_t y);
+
+#if U_IS_BIG_ENDIAN
+#   define uprv_isNegative(number) (*((signed char *)&(number))<0)
+#else
+#   define uprv_isNegative(number) (*((signed char *)&(number)+sizeof(number)-1)<0)
+#endif
+
+/**
+ * Return the largest positive number that can be represented by an integer
+ * type of arbitrary bit length.
+ * @internal
+ */
+U_INTERNAL double  U_EXPORT2 uprv_maxMantissa(void);
+
+/**
+ * Floating point utility to calculate the logarithm of a double.
+ * @internal
+ */
+U_INTERNAL double  U_EXPORT2 uprv_log(double d);
+
+/**
+ * Does common notion of rounding e.g. uprv_floor(x + 0.5);
+ * @param x the double number
+ * @return the rounded double
+ * @internal
+ */
+U_INTERNAL double  U_EXPORT2 uprv_round(double x);
+
+#if 0
+/**
+ * Returns the number of digits after the decimal point in a double number x.
+ *
+ * @param x the double number
+ * @return the number of digits after the decimal point in a double number x.
+ * @internal
+ */
+/*U_INTERNAL int32_t  U_EXPORT2 uprv_digitsAfterDecimal(double x);*/
+#endif
+
+/**
+ * Time zone utilities
+ *
+ * Wrappers for C runtime library functions relating to timezones.
+ * The t_tzset() function (similar to tzset) uses the current setting
+ * of the environment variable TZ to assign values to three global
+ * variables: daylight, timezone, and tzname. These variables have the
+ * following meanings, and are declared in &lt;time.h&gt;.
+ *
+ *   daylight   Nonzero if daylight-saving-time zone (DST) is specified
+ *              in TZ; otherwise, 0. Default value is 1.
+ *   timezone   Difference in seconds between coordinated universal
+ *              time and local time. E.g., -28,800 for PST (GMT-8hrs)
+ *   tzname(0)  Three-letter time-zone name derived from TZ environment
+ *              variable. E.g., "PST".
+ *   tzname(1)  Three-letter DST zone name derived from TZ environment
+ *              variable.  E.g., "PDT". If DST zone is omitted from TZ,
+ *              tzname(1) is an empty string.
+ *
+ * Notes: For example, to set the TZ environment variable to correspond
+ * to the current time zone in Germany, you can use one of the
+ * following statements:
+ *
+ *   set TZ=GST1GDT
+ *   set TZ=GST+1GDT
+ *
+ * If the TZ value is not set, t_tzset() attempts to use the time zone
+ * information specified by the operating system. Under Windows NT
+ * and Windows 95, this information is specified in the Control Panel's
+ * Date/Time application.
+ * @internal
+ */
+U_INTERNAL void     U_EXPORT2 uprv_tzset(void);
+
+/**
+ * Difference in seconds between coordinated universal
+ * time and local time. E.g., -28,800 for PST (GMT-8hrs)
+ * @return the difference in seconds between coordinated universal time and local time.
+ * @internal
+ */
+U_INTERNAL int32_t  U_EXPORT2 uprv_timezone(void);
+
+/**
+ *   tzname(0)  Three-letter time-zone name derived from TZ environment
+ *              variable. E.g., "PST".
+ *   tzname(1)  Three-letter DST zone name derived from TZ environment
+ *              variable.  E.g., "PDT". If DST zone is omitted from TZ,
+ *              tzname(1) is an empty string.
+ * @internal
+ */
+U_INTERNAL const char* U_EXPORT2 uprv_tzname(int n);
+
+/**
+ * Get UTC (GMT) time measured in milliseconds since 0:00 on 1/1/1970.
+ * @return the UTC time measured in milliseconds
+ * @internal
+ */
+U_INTERNAL UDate U_EXPORT2 uprv_getUTCtime(void);
+
+/**
+ * Determine whether a pathname is absolute or not, as defined by the platform.
+ * @param path Pathname to test
+ * @return TRUE if the path is absolute
+ * @internal (ICU 3.0)
+ */
+U_INTERNAL UBool U_EXPORT2 uprv_pathIsAbsolute(const char *path);
+
+/**
+ * Use U_MAX_PTR instead of this function.
+ * @param void pointer to test
+ * @return the largest possible pointer greater than the base
+ * @internal (ICU 3.8)
+ */
+U_INTERNAL void * U_EXPORT2 uprv_maximumPtr(void *base);
+
+/**
+ * Maximum value of a (void*) - use to indicate the limit of an 'infinite' buffer.
+ * In fact, buffer sizes must not exceed 2GB so that the difference between
+ * the buffer limit and the buffer start can be expressed in an int32_t.
+ *
+ * The definition of U_MAX_PTR must fulfill the following conditions:
+ * - return the largest possible pointer greater than base
+ * - return a valid pointer according to the machine architecture (AS/400, 64-bit, etc.)
+ * - avoid wrapping around at high addresses
+ * - make sure that the returned pointer is not farther from base than 0x7fffffff
+ *
+ * @param base The beginning of a buffer to find the maximum offset from
+ * @internal
+ */
+#ifndef U_MAX_PTR
+#  if defined(OS390) && !defined(_LP64)
+    /* We have 31-bit pointers. */
+#    define U_MAX_PTR(base) ((void *)0x7fffffff)
+#  elif defined(OS400)
+#    define U_MAX_PTR(base) uprv_maximumPtr((void *)base)
+#  elif defined(__GNUC__) && __GNUC__ >= 4
+/*
+ * Due to a compiler optimization bug, gcc 4 causes test failures when doing
+ * this math arithmetic on pointers on some platforms. It seems like the
+ * pointers are considered signed instead of unsigned. The uintptr_t type
+ * isn't available on all platforms (i.e MSVC 6) and pointers aren't always
+ * a scalar value (i.e. i5/OS see uprv_maximumPtr function).
+ */
+#    define U_MAX_PTR(base) \
+    ((void *)(((uintptr_t)(base)+0x7fffffffu) > (uintptr_t)(base) \
+        ? ((uintptr_t)(base)+0x7fffffffu) \
+        : (uintptr_t)-1))
+#  else
+#    define U_MAX_PTR(base) \
+    ((char *)(((char *)(base)+0x7fffffffu) > (char *)(base) \
+        ? ((char *)(base)+0x7fffffffu) \
+        : (char *)-1))
+#  endif
+#endif
+
+#if U_ENABLE_DYLOAD
+/*  Dynamic Library Functions */
+
+/**
+ * Load a library
+ * @internal (ICU 4.4)
+ */
+U_INTERNAL void * U_EXPORT2 uprv_dl_open(const char *libName, UErrorCode *status);
+
+/**
+ * Close a library
+ * @internal (ICU 4.4)
+ */
+U_INTERNAL void U_EXPORT2 uprv_dl_close( void *lib, UErrorCode *status);
+
+/**
+ * Extract a symbol from a library
+ * @internal (ICU 4.4)
+ */
+U_INTERNAL void * U_EXPORT2 uprv_dl_sym( void *lib, const char *symbolName, UErrorCode *status);
+
+#endif
+
+#endif
diff --git a/icu/source/common/rbbi.cpp b/icu/source/common/rbbi.cpp
new file mode 100644
index 0000000..5308e26
--- /dev/null
+++ b/icu/source/common/rbbi.cpp
@@ -0,0 +1,1855 @@
+/*
+***************************************************************************
+*   Copyright (C) 1999-2009 International Business Machines Corporation   *
+*   and others. All rights reserved.                                      *
+***************************************************************************
+*/
+//
+//  file:  rbbi.c    Contains the implementation of the rule based break iterator
+//                   runtime engine and the API implementation for
+//                   class RuleBasedBreakIterator
+//
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/rbbi.h"
+#include "unicode/schriter.h"
+#include "unicode/uchriter.h"
+#include "unicode/udata.h"
+#include "unicode/uclean.h"
+#include "rbbidata.h"
+#include "rbbirb.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "umutex.h"
+#include "ucln_cmn.h"
+#include "brkeng.h"
+
+#include "uassert.h"
+#include "uvector.h"
+
+// if U_LOCAL_SERVICE_HOOK is defined, then localsvc.cpp is expected to be included.
+#if U_LOCAL_SERVICE_HOOK
+#include "localsvc.h"
+#endif
+
+#ifdef RBBI_DEBUG
+static UBool fTrace = FALSE;
+#endif
+
+U_NAMESPACE_BEGIN
+
+// The state number of the starting state
+#define START_STATE 1
+
+// The state-transition value indicating "stop"
+#define STOP_STATE  0
+
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RuleBasedBreakIterator)
+
+
+//=======================================================================
+// constructors
+//=======================================================================
+
+/**
+ * Constructs a RuleBasedBreakIterator that uses the already-created
+ * tables object that is passed in as a parameter.
+ */
+RuleBasedBreakIterator::RuleBasedBreakIterator(RBBIDataHeader* data, UErrorCode &status)
+{
+    init();
+    fData = new RBBIDataWrapper(data, status); // status checked in constructor
+    if (U_FAILURE(status)) {return;}
+    if(fData == 0) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+}
+
+/**
+ * Same as above but does not adopt memory
+ */
+RuleBasedBreakIterator::RuleBasedBreakIterator(const RBBIDataHeader* data, enum EDontAdopt, UErrorCode &status)
+{
+    init();
+    fData = new RBBIDataWrapper(data, RBBIDataWrapper::kDontAdopt, status); // status checked in constructor
+    if (U_FAILURE(status)) {return;}
+    if(fData == 0) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+}
+
+//-------------------------------------------------------------------------------
+//
+//   Constructor   from a UDataMemory handle to precompiled break rules
+//                 stored in an ICU data file.
+//
+//-------------------------------------------------------------------------------
+RuleBasedBreakIterator::RuleBasedBreakIterator(UDataMemory* udm, UErrorCode &status)
+{
+    init();
+    fData = new RBBIDataWrapper(udm, status); // status checked in constructor
+    if (U_FAILURE(status)) {return;}
+    if(fData == 0) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+}
+
+
+
+//-------------------------------------------------------------------------------
+//
+//   Constructor       from a set of rules supplied as a string.
+//
+//-------------------------------------------------------------------------------
+RuleBasedBreakIterator::RuleBasedBreakIterator( const UnicodeString  &rules,
+                                                UParseError          &parseError,
+                                                UErrorCode           &status)
+{
+    init();
+    if (U_FAILURE(status)) {return;}
+    RuleBasedBreakIterator *bi = (RuleBasedBreakIterator *)
+        RBBIRuleBuilder::createRuleBasedBreakIterator(rules, &parseError, status);
+    // Note:  This is a bit awkward.  The RBBI ruleBuilder has a factory method that
+    //        creates and returns a complete RBBI.  From here, in a constructor, we
+    //        can't just return the object created by the builder factory, hence
+    //        the assignment of the factory created object to "this".
+    if (U_SUCCESS(status)) {
+        *this = *bi;
+        delete bi;
+    }
+}
+
+
+//-------------------------------------------------------------------------------
+//
+// Default Constructor.      Create an empty shell that can be set up later.
+//                           Used when creating a RuleBasedBreakIterator from a set
+//                           of rules.
+//-------------------------------------------------------------------------------
+RuleBasedBreakIterator::RuleBasedBreakIterator() {
+    init();
+}
+
+
+//-------------------------------------------------------------------------------
+//
+//   Copy constructor.  Will produce a break iterator with the same behavior,
+//                      and which iterates over the same text, as the one passed in.
+//
+//-------------------------------------------------------------------------------
+RuleBasedBreakIterator::RuleBasedBreakIterator(const RuleBasedBreakIterator& other)
+: BreakIterator(other)
+{
+    this->init();
+    *this = other;
+}
+
+
+/**
+ * Destructor
+ */
+RuleBasedBreakIterator::~RuleBasedBreakIterator() {
+    if (fCharIter!=fSCharIter && fCharIter!=fDCharIter) {
+        // fCharIter was adopted from the outside.
+        delete fCharIter;
+    }
+    fCharIter = NULL;
+    delete fSCharIter;
+    fCharIter = NULL;
+    delete fDCharIter;
+    fDCharIter = NULL;
+    
+    utext_close(fText);
+
+    if (fData != NULL) {
+        fData->removeReference();
+        fData = NULL;
+    }
+    if (fCachedBreakPositions) {
+        uprv_free(fCachedBreakPositions);
+        fCachedBreakPositions = NULL;
+    }
+    if (fLanguageBreakEngines) {
+        delete fLanguageBreakEngines;
+        fLanguageBreakEngines = NULL;
+    }
+    if (fUnhandledBreakEngine) {
+        delete fUnhandledBreakEngine;
+        fUnhandledBreakEngine = NULL;
+    }
+}
+
+/**
+ * Assignment operator.  Sets this iterator to have the same behavior,
+ * and iterate over the same text, as the one passed in.
+ */
+RuleBasedBreakIterator&
+RuleBasedBreakIterator::operator=(const RuleBasedBreakIterator& that) {
+    if (this == &that) {
+        return *this;
+    }
+    reset();    // Delete break cache information
+    fBreakType = that.fBreakType;
+    if (fLanguageBreakEngines != NULL) {
+        delete fLanguageBreakEngines;
+        fLanguageBreakEngines = NULL;   // Just rebuild for now
+    }
+    // TODO: clone fLanguageBreakEngines from "that"
+    UErrorCode status = U_ZERO_ERROR;
+    fText = utext_clone(fText, that.fText, FALSE, TRUE, &status);
+
+    if (fCharIter!=fSCharIter && fCharIter!=fDCharIter) {
+        delete fCharIter;
+    }
+    fCharIter = NULL;
+
+    if (that.fCharIter != NULL ) {
+        // This is a little bit tricky - it will intially appear that
+        //  this->fCharIter is adopted, even if that->fCharIter was
+        //  not adopted.  That's ok.
+        fCharIter = that.fCharIter->clone();
+    }
+
+    if (fData != NULL) {
+        fData->removeReference();
+        fData = NULL;
+    }
+    if (that.fData != NULL) {
+        fData = that.fData->addReference();
+    }
+
+    return *this;
+}
+
+
+
+//-----------------------------------------------------------------------------
+//
+//    init()      Shared initialization routine.   Used by all the constructors.
+//                Initializes all fields, leaving the object in a consistent state.
+//
+//-----------------------------------------------------------------------------
+void RuleBasedBreakIterator::init() {
+    UErrorCode  status    = U_ZERO_ERROR;
+    fBufferClone          = FALSE;
+    fText                 = utext_openUChars(NULL, NULL, 0, &status);
+    fCharIter             = NULL;
+    fSCharIter            = NULL;
+    fDCharIter            = NULL;
+    fData                 = NULL;
+    fLastRuleStatusIndex  = 0;
+    fLastStatusIndexValid = TRUE;
+    fDictionaryCharCount  = 0;
+    fBreakType            = UBRK_WORD;  // Defaulting BreakType to word gives reasonable
+                                        //   dictionary behavior for Break Iterators that are
+                                        //   built from rules.  Even better would be the ability to
+                                        //   declare the type in the rules.
+
+    fCachedBreakPositions    = NULL;
+    fLanguageBreakEngines    = NULL;
+    fUnhandledBreakEngine    = NULL;
+    fNumCachedBreakPositions = 0;
+    fPositionInCache         = 0;
+
+#ifdef RBBI_DEBUG
+    static UBool debugInitDone = FALSE;
+    if (debugInitDone == FALSE) {
+        char *debugEnv = getenv("U_RBBIDEBUG");
+        if (debugEnv && uprv_strstr(debugEnv, "trace")) {
+            fTrace = TRUE;
+        }
+        debugInitDone = TRUE;
+    }
+#endif
+}
+
+
+
+//-----------------------------------------------------------------------------
+//
+//    clone - Returns a newly-constructed RuleBasedBreakIterator with the same
+//            behavior, and iterating over the same text, as this one.
+//            Virtual function: does the right thing with subclasses.
+//
+//-----------------------------------------------------------------------------
+BreakIterator*
+RuleBasedBreakIterator::clone(void) const {
+    return new RuleBasedBreakIterator(*this);
+}
+
+/**
+ * Equality operator.  Returns TRUE if both BreakIterators are of the
+ * same class, have the same behavior, and iterate over the same text.
+ */
+UBool
+RuleBasedBreakIterator::operator==(const BreakIterator& that) const {
+    if (that.getDynamicClassID() != getDynamicClassID()) {
+        return FALSE;
+    }
+
+    const RuleBasedBreakIterator& that2 = (const RuleBasedBreakIterator&) that;
+
+    if (!utext_equals(fText, that2.fText)) {
+        // The two break iterators are operating on different text,
+        //   or have a different interation position.
+        return FALSE;
+    };
+
+    // TODO:  need a check for when in a dictionary region at different offsets.
+
+    if (that2.fData == fData ||
+        (fData != NULL && that2.fData != NULL && *that2.fData == *fData)) {
+            // The two break iterators are using the same rules.
+            return TRUE;
+        }
+    return FALSE;
+}
+
+/**
+ * Compute a hash code for this BreakIterator
+ * @return A hash code
+ */
+int32_t
+RuleBasedBreakIterator::hashCode(void) const {
+    int32_t   hash = 0;
+    if (fData != NULL) {
+        hash = fData->hashCode();
+    }
+    return hash;
+}
+
+
+void RuleBasedBreakIterator::setText(UText *ut, UErrorCode &status) {
+    if (U_FAILURE(status)) {
+        return;
+    }
+    reset();
+    fText = utext_clone(fText, ut, FALSE, TRUE, &status);
+
+    // Set up a dummy CharacterIterator to be returned if anyone
+    //   calls getText().  With input from UText, there is no reasonable
+    //   way to return a characterIterator over the actual input text.
+    //   Return one over an empty string instead - this is the closest
+    //   we can come to signaling a failure.
+    //   (GetText() is obsolete, this failure is sort of OK)
+    if (fDCharIter == NULL) {
+        static const UChar c = 0;
+        fDCharIter = new UCharCharacterIterator(&c, 0);
+        if (fDCharIter == NULL) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+    }
+
+    if (fCharIter!=fSCharIter && fCharIter!=fDCharIter) {
+        // existing fCharIter was adopted from the outside.  Delete it now.
+        delete fCharIter;
+    }
+    fCharIter = fDCharIter;
+
+    this->first();
+}
+
+
+UText *RuleBasedBreakIterator::getUText(UText *fillIn, UErrorCode &status) const {
+    UText *result = utext_clone(fillIn, fText, FALSE, TRUE, &status);  
+    return result;
+}
+
+
+
+/**
+ * Returns the description used to create this iterator
+ */
+const UnicodeString&
+RuleBasedBreakIterator::getRules() const {
+    if (fData != NULL) {
+        return fData->getRuleSourceString();
+    } else {
+        static const UnicodeString *s;
+        if (s == NULL) {
+            // TODO:  something more elegant here.
+            //        perhaps API should return the string by value.
+            //        Note:  thread unsafe init & leak are semi-ok, better than
+            //               what was before.  Sould be cleaned up, though.
+            s = new UnicodeString;
+        }
+        return *s;
+    }
+}
+
+//=======================================================================
+// BreakIterator overrides
+//=======================================================================
+
+/**
+ * Return a CharacterIterator over the text being analyzed.  
+ */
+CharacterIterator&
+RuleBasedBreakIterator::getText() const {
+    return *fCharIter;
+}
+
+/**
+ * Set the iterator to analyze a new piece of text.  This function resets
+ * the current iteration position to the beginning of the text.
+ * @param newText An iterator over the text to analyze.
+ */
+void
+RuleBasedBreakIterator::adoptText(CharacterIterator* newText) {
+    // If we are holding a CharacterIterator adopted from a 
+    //   previous call to this function, delete it now.
+    if (fCharIter!=fSCharIter && fCharIter!=fDCharIter) {
+        delete fCharIter;
+    }
+
+    fCharIter = newText;
+    UErrorCode status = U_ZERO_ERROR;
+    reset();
+    if (newText==NULL || newText->startIndex() != 0) {   
+        // startIndex !=0 wants to be an error, but there's no way to report it.
+        // Make the iterator text be an empty string.
+        fText = utext_openUChars(fText, NULL, 0, &status);
+    } else {
+        fText = utext_openCharacterIterator(fText, newText, &status);
+    }
+    this->first();
+}
+
+/**
+ * Set the iterator to analyze a new piece of text.  This function resets
+ * the current iteration position to the beginning of the text.
+ * @param newText An iterator over the text to analyze.
+ */
+void
+RuleBasedBreakIterator::setText(const UnicodeString& newText) {
+    UErrorCode status = U_ZERO_ERROR;
+    reset();
+    fText = utext_openConstUnicodeString(fText, &newText, &status);
+
+    // Set up a character iterator on the string.  
+    //   Needed in case someone calls getText().
+    //  Can not, unfortunately, do this lazily on the (probably never)
+    //  call to getText(), because getText is const.
+    if (fSCharIter == NULL) {
+        fSCharIter = new StringCharacterIterator(newText);
+    } else {
+        fSCharIter->setText(newText);
+    }
+
+    if (fCharIter!=fSCharIter && fCharIter!=fDCharIter) {
+        // old fCharIter was adopted from the outside.  Delete it.
+        delete fCharIter;
+    }
+    fCharIter = fSCharIter;
+
+    this->first();
+}
+
+
+
+/**
+ * Sets the current iteration position to the beginning of the text.
+ * @return The offset of the beginning of the text.
+ */
+int32_t RuleBasedBreakIterator::first(void) {
+    reset();
+    fLastRuleStatusIndex  = 0;
+    fLastStatusIndexValid = TRUE;
+    //if (fText == NULL)
+    //    return BreakIterator::DONE;
+
+    utext_setNativeIndex(fText, 0);
+    return 0;
+}
+
+/**
+ * Sets the current iteration position to the end of the text.
+ * @return The text's past-the-end offset.
+ */
+int32_t RuleBasedBreakIterator::last(void) {
+    reset();
+    if (fText == NULL) {
+        fLastRuleStatusIndex  = 0;
+        fLastStatusIndexValid = TRUE;
+        return BreakIterator::DONE;
+    }
+
+    fLastStatusIndexValid = FALSE;
+    int32_t pos = (int32_t)utext_nativeLength(fText);
+    utext_setNativeIndex(fText, pos);
+    return pos;
+}
+
+/**
+ * Advances the iterator either forward or backward the specified number of steps.
+ * Negative values move backward, and positive values move forward.  This is
+ * equivalent to repeatedly calling next() or previous().
+ * @param n The number of steps to move.  The sign indicates the direction
+ * (negative is backwards, and positive is forwards).
+ * @return The character offset of the boundary position n boundaries away from
+ * the current one.
+ */
+int32_t RuleBasedBreakIterator::next(int32_t n) {
+    int32_t result = current();
+    while (n > 0) {
+        result = next();
+        --n;
+    }
+    while (n < 0) {
+        result = previous();
+        ++n;
+    }
+    return result;
+}
+
+/**
+ * Advances the iterator to the next boundary position.
+ * @return The position of the first boundary after this one.
+ */
+int32_t RuleBasedBreakIterator::next(void) {
+    // if we have cached break positions and we're still in the range
+    // covered by them, just move one step forward in the cache
+    if (fCachedBreakPositions != NULL) {
+        if (fPositionInCache < fNumCachedBreakPositions - 1) {
+            ++fPositionInCache;
+            int32_t pos = fCachedBreakPositions[fPositionInCache];
+            utext_setNativeIndex(fText, pos);
+            return pos;
+        }
+        else {
+            reset();
+        }
+    }
+
+    int32_t startPos = current();
+    int32_t result = handleNext(fData->fForwardTable);
+    if (fDictionaryCharCount > 0) {
+        result = checkDictionary(startPos, result, FALSE);
+    }
+    return result;
+}
+
+/**
+ * Advances the iterator backwards, to the last boundary preceding this one.
+ * @return The position of the last boundary position preceding this one.
+ */
+int32_t RuleBasedBreakIterator::previous(void) {
+    int32_t result;
+    int32_t startPos;
+
+    // if we have cached break positions and we're still in the range
+    // covered by them, just move one step backward in the cache
+    if (fCachedBreakPositions != NULL) {
+        if (fPositionInCache > 0) {
+            --fPositionInCache;
+            // If we're at the beginning of the cache, need to reevaluate the
+            // rule status
+            if (fPositionInCache <= 0) {
+                fLastStatusIndexValid = FALSE;
+            }
+            int32_t pos = fCachedBreakPositions[fPositionInCache];
+            utext_setNativeIndex(fText, pos);
+            return pos;
+        }
+        else {
+            reset();
+        }
+    }
+
+    // if we're already sitting at the beginning of the text, return DONE
+    if (fText == NULL || (startPos = current()) == 0) {
+        fLastRuleStatusIndex  = 0;
+        fLastStatusIndexValid = TRUE;
+        return BreakIterator::DONE;
+    }
+
+    if (fData->fSafeRevTable != NULL || fData->fSafeFwdTable != NULL) {
+        result = handlePrevious(fData->fReverseTable);
+        if (fDictionaryCharCount > 0) {
+            result = checkDictionary(result, startPos, TRUE);
+        }
+        return result;
+    }
+
+    // old rule syntax
+    // set things up.  handlePrevious() will back us up to some valid
+    // break position before the current position (we back our internal
+    // iterator up one step to prevent handlePrevious() from returning
+    // the current position), but not necessarily the last one before
+
+    // where we started
+
+    int32_t start = current();
+
+    UTEXT_PREVIOUS32(fText);
+    int32_t lastResult    = handlePrevious(fData->fReverseTable);
+    if (lastResult == UBRK_DONE) {
+        lastResult = 0;
+        utext_setNativeIndex(fText, 0);
+    }
+    result = lastResult;
+    int32_t lastTag       = 0;
+    UBool   breakTagValid = FALSE;
+
+    // iterate forward from the known break position until we pass our
+    // starting point.  The last break position before the starting
+    // point is our return value
+
+    for (;;) {
+        result         = next();
+        if (result == BreakIterator::DONE || result >= start) {
+            break;
+        }
+        lastResult     = result;
+        lastTag        = fLastRuleStatusIndex;
+        breakTagValid  = TRUE;
+    }
+
+    // fLastBreakTag wants to have the value for section of text preceding
+    // the result position that we are to return (in lastResult.)  If
+    // the backwards rules overshot and the above loop had to do two or more
+    // next()s to move up to the desired return position, we will have a valid
+    // tag value. But, if handlePrevious() took us to exactly the correct result positon,
+    // we wont have a tag value for that position, which is only set by handleNext().
+
+    // set the current iteration position to be the last break position
+    // before where we started, and then return that value
+    utext_setNativeIndex(fText, lastResult);
+    fLastRuleStatusIndex  = lastTag;       // for use by getRuleStatus()
+    fLastStatusIndexValid = breakTagValid;
+
+    // No need to check the dictionary; it will have been handled by
+    // next()
+
+    return lastResult;
+}
+
+/**
+ * Sets the iterator to refer to the first boundary position following
+ * the specified position.
+ * @offset The position from which to begin searching for a break position.
+ * @return The position of the first break after the current position.
+ */
+int32_t RuleBasedBreakIterator::following(int32_t offset) {
+    // if we have cached break positions and offset is in the range
+    // covered by them, use them
+    // TODO: could use binary search
+    // TODO: what if offset is outside range, but break is not?
+    if (fCachedBreakPositions != NULL) {
+        if (offset >= fCachedBreakPositions[0]
+                && offset < fCachedBreakPositions[fNumCachedBreakPositions - 1]) {
+            fPositionInCache = 0;
+            // We are guaranteed not to leave the array due to range test above
+            while (offset >= fCachedBreakPositions[fPositionInCache]) {
+                ++fPositionInCache;
+            }
+            int32_t pos = fCachedBreakPositions[fPositionInCache];
+            utext_setNativeIndex(fText, pos);
+            return pos;
+        }
+        else {
+            reset();
+        }
+    }
+
+    // if the offset passed in is already past the end of the text,
+    // just return DONE; if it's before the beginning, return the
+    // text's starting offset
+    fLastRuleStatusIndex  = 0;
+    fLastStatusIndexValid = TRUE;
+    if (fText == NULL || offset >= utext_nativeLength(fText)) {
+        last();
+        return next();
+    }
+    else if (offset < 0) {
+        return first();
+    }
+
+    // otherwise, set our internal iteration position (temporarily)
+    // to the position passed in.  If this is the _beginning_ position,
+    // then we can just use next() to get our return value
+
+    int32_t result = 0;
+
+    if (fData->fSafeRevTable != NULL) {
+        // new rule syntax
+        utext_setNativeIndex(fText, offset);
+        // move forward one codepoint to prepare for moving back to a
+        // safe point.
+        // this handles offset being between a supplementary character
+        UTEXT_NEXT32(fText);
+        // handlePrevious will move most of the time to < 1 boundary away
+        handlePrevious(fData->fSafeRevTable);
+        int32_t result = next();
+        while (result <= offset) {
+            result = next();
+        }
+        return result;
+    }
+    if (fData->fSafeFwdTable != NULL) {
+        // backup plan if forward safe table is not available
+        utext_setNativeIndex(fText, offset);
+        UTEXT_PREVIOUS32(fText);
+        // handle next will give result >= offset
+        handleNext(fData->fSafeFwdTable);
+        // previous will give result 0 or 1 boundary away from offset,
+        // most of the time
+        // we have to
+        int32_t oldresult = previous();
+        while (oldresult > offset) {
+            int32_t result = previous();
+            if (result <= offset) {
+                return oldresult;
+            }
+            oldresult = result;
+        }
+        int32_t result = next();
+        if (result <= offset) {
+            return next();
+        }
+        return result;
+    }
+    // otherwise, we have to sync up first.  Use handlePrevious() to back
+    // up to a known break position before the specified position (if
+    // we can determine that the specified position is a break position,
+    // we don't back up at all).  This may or may not be the last break
+    // position at or before our starting position.  Advance forward
+    // from here until we've passed the starting position.  The position
+    // we stop on will be the first break position after the specified one.
+    // old rule syntax
+
+    utext_setNativeIndex(fText, offset);
+    if (offset==0 || 
+        offset==1  && utext_getNativeIndex(fText)==0) {
+        return next();
+    }
+    result = previous();
+
+    while (result != BreakIterator::DONE && result <= offset) {
+        result = next();
+    }
+
+    return result;
+}
+
+/**
+ * Sets the iterator to refer to the last boundary position before the
+ * specified position.
+ * @offset The position to begin searching for a break from.
+ * @return The position of the last boundary before the starting position.
+ */
+int32_t RuleBasedBreakIterator::preceding(int32_t offset) {
+    // if we have cached break positions and offset is in the range
+    // covered by them, use them
+    if (fCachedBreakPositions != NULL) {
+        // TODO: binary search?
+        // TODO: What if offset is outside range, but break is not?
+        if (offset > fCachedBreakPositions[0]
+                && offset <= fCachedBreakPositions[fNumCachedBreakPositions - 1]) {
+            fPositionInCache = 0;
+            while (fPositionInCache < fNumCachedBreakPositions
+                   && offset > fCachedBreakPositions[fPositionInCache])
+                ++fPositionInCache;
+            --fPositionInCache;
+            // If we're at the beginning of the cache, need to reevaluate the
+            // rule status
+            if (fPositionInCache <= 0) {
+                fLastStatusIndexValid = FALSE;
+            }
+            utext_setNativeIndex(fText, fCachedBreakPositions[fPositionInCache]);
+            return fCachedBreakPositions[fPositionInCache];
+        }
+        else {
+            reset();
+        }
+    }
+
+    // if the offset passed in is already past the end of the text,
+    // just return DONE; if it's before the beginning, return the
+    // text's starting offset
+    if (fText == NULL || offset > utext_nativeLength(fText)) {
+        // return BreakIterator::DONE;
+        return last();
+    }
+    else if (offset < 0) {
+        return first();
+    }
+
+    // if we start by updating the current iteration position to the
+    // position specified by the caller, we can just use previous()
+    // to carry out this operation
+
+    if (fData->fSafeFwdTable != NULL) {
+        // new rule syntax
+        utext_setNativeIndex(fText, offset);
+        int32_t newOffset = (int32_t)UTEXT_GETNATIVEINDEX(fText);
+        if (newOffset != offset) {
+            // Will come here if specified offset was not a code point boundary AND
+            //   the underlying implmentation is using UText, which snaps any non-code-point-boundary
+            //   indices to the containing code point.
+            // For breakitereator::preceding only, these non-code-point indices need to be moved
+            //   up to refer to the following codepoint.
+            UTEXT_NEXT32(fText);
+            offset = (int32_t)UTEXT_GETNATIVEINDEX(fText);
+        }
+
+        // TODO:  (synwee) would it be better to just check for being in the middle of a surrogate pair,
+        //        rather than adjusting the position unconditionally?
+        //        (Change would interact with safe rules.)
+        // TODO:  change RBBI behavior for off-boundary indices to match that of UText?
+        //        affects only preceding(), seems cleaner, but is slightly different.
+        UTEXT_PREVIOUS32(fText);
+        handleNext(fData->fSafeFwdTable);
+        int32_t result = (int32_t)UTEXT_GETNATIVEINDEX(fText);
+        while (result >= offset) {
+            result = previous();
+        }
+        return result;
+    }
+    if (fData->fSafeRevTable != NULL) {
+        // backup plan if forward safe table is not available
+        //  TODO:  check whether this path can be discarded
+        //         It's probably OK to say that rules must supply both safe tables
+        //            if they use safe tables at all.  We have certainly never described
+        //            to anyone how to work with just one safe table.
+        utext_setNativeIndex(fText, offset);
+        UTEXT_NEXT32(fText);
+        
+        // handle previous will give result <= offset
+        handlePrevious(fData->fSafeRevTable);
+
+        // next will give result 0 or 1 boundary away from offset,
+        // most of the time
+        // we have to
+        int32_t oldresult = next();
+        while (oldresult < offset) {
+            int32_t result = next();
+            if (result >= offset) {
+                return oldresult;
+            }
+            oldresult = result;
+        }
+        int32_t result = previous();
+        if (result >= offset) {
+            return previous();
+        }
+        return result;
+    }
+
+    // old rule syntax
+    utext_setNativeIndex(fText, offset);
+    return previous();
+}
+
+/**
+ * Returns true if the specfied position is a boundary position.  As a side
+ * effect, leaves the iterator pointing to the first boundary position at
+ * or after "offset".
+ * @param offset the offset to check.
+ * @return True if "offset" is a boundary position.
+ */
+UBool RuleBasedBreakIterator::isBoundary(int32_t offset) {
+    // the beginning index of the iterator is always a boundary position by definition
+    if (offset == 0) {
+        first();       // For side effects on current position, tag values.
+        return TRUE;
+    }
+
+    if (offset == (int32_t)utext_nativeLength(fText)) {
+        last();       // For side effects on current position, tag values.
+        return TRUE;
+    }
+
+    // out-of-range indexes are never boundary positions
+    if (offset < 0) {
+        first();       // For side effects on current position, tag values.
+        return FALSE;
+    }
+
+    if (offset > utext_nativeLength(fText)) {
+        last();        // For side effects on current position, tag values.
+        return FALSE;
+    }
+
+    // otherwise, we can use following() on the position before the specified
+    // one and return true if the position we get back is the one the user
+    // specified
+    utext_previous32From(fText, offset);
+    int32_t backOne = (int32_t)UTEXT_GETNATIVEINDEX(fText);
+    UBool    result  = following(backOne) == offset;
+    return result;
+}
+
+/**
+ * Returns the current iteration position.
+ * @return The current iteration position.
+ */
+int32_t RuleBasedBreakIterator::current(void) const {
+    int32_t  pos = (int32_t)UTEXT_GETNATIVEINDEX(fText);
+    return pos;
+}
+ 
+//=======================================================================
+// implementation
+//=======================================================================
+
+//
+// RBBIRunMode  -  the state machine runs an extra iteration at the beginning and end
+//                 of user text.  A variable with this enum type keeps track of where we
+//                 are.  The state machine only fetches user input while in the RUN mode.
+//
+enum RBBIRunMode {
+    RBBI_START,     // state machine processing is before first char of input
+    RBBI_RUN,       // state machine processing is in the user text
+    RBBI_END        // state machine processing is after end of user text.
+};
+
+
+//-----------------------------------------------------------------------------------
+//
+//  handleNext(stateTable)
+//     This method is the actual implementation of the rbbi next() method. 
+//     This method initializes the state machine to state 1
+//     and advances through the text character by character until we reach the end
+//     of the text or the state machine transitions to state 0.  We update our return
+//     value every time the state machine passes through an accepting state.
+//
+//-----------------------------------------------------------------------------------
+int32_t RuleBasedBreakIterator::handleNext(const RBBIStateTable *statetable) {
+    int32_t             state;
+    int16_t             category        = 0;
+    RBBIRunMode         mode;
+    
+    RBBIStateTableRow  *row;
+    UChar32             c;
+    int32_t             lookaheadStatus = 0;
+    int32_t             lookaheadTagIdx = 0;
+    int32_t             result          = 0;
+    int32_t             initialPosition = 0;
+    int32_t             lookaheadResult = 0;
+    UBool               lookAheadHardBreak = (statetable->fFlags & RBBI_LOOKAHEAD_HARD_BREAK) != 0;
+    const char         *tableData       = statetable->fTableData;
+    uint32_t            tableRowLen     = statetable->fRowLen;
+
+    #ifdef RBBI_DEBUG
+        if (fTrace) {
+            RBBIDebugPuts("Handle Next   pos   char  state category");
+        }
+    #endif
+
+    // No matter what, handleNext alway correctly sets the break tag value.
+    fLastStatusIndexValid = TRUE;
+    fLastRuleStatusIndex = 0;
+
+    // if we're already at the end of the text, return DONE.
+    initialPosition = (int32_t)UTEXT_GETNATIVEINDEX(fText); 
+    result          = initialPosition;
+    c               = UTEXT_NEXT32(fText);
+    if (fData == NULL || c==U_SENTINEL) {
+        return BreakIterator::DONE;
+    }
+
+    //  Set the initial state for the state machine
+    state = START_STATE;
+    row = (RBBIStateTableRow *)
+            //(statetable->fTableData + (statetable->fRowLen * state));
+            (tableData + tableRowLen * state);
+            
+    
+    mode     = RBBI_RUN;
+    if (statetable->fFlags & RBBI_BOF_REQUIRED) {
+        category = 2;
+        mode     = RBBI_START;
+    }
+
+
+    // loop until we reach the end of the text or transition to state 0
+    //
+    for (;;) {
+        if (c == U_SENTINEL) {
+            // Reached end of input string.
+            if (mode == RBBI_END) {
+                // We have already run the loop one last time with the 
+                //   character set to the psueudo {eof} value.  Now it is time
+                //   to unconditionally bail out.
+                if (lookaheadResult > result) {
+                    // We ran off the end of the string with a pending look-ahead match.
+                    // Treat this as if the look-ahead condition had been met, and return
+                    //  the match at the / position from the look-ahead rule.
+                    result               = lookaheadResult;
+                    fLastRuleStatusIndex = lookaheadTagIdx;
+                    lookaheadStatus = 0;
+                } 
+                break;
+            }
+            // Run the loop one last time with the fake end-of-input character category.
+            mode = RBBI_END;
+            category = 1;
+        }
+
+        //
+        // Get the char category.  An incoming category of 1 or 2 means that
+        //      we are preset for doing the beginning or end of input, and
+        //      that we shouldn't get a category from an actual text input character.
+        //
+        if (mode == RBBI_RUN) {
+            // look up the current character's character category, which tells us
+            // which column in the state table to look at.
+            // Note:  the 16 in UTRIE_GET16 refers to the size of the data being returned,
+            //        not the size of the character going in, which is a UChar32.
+            //
+            UTRIE_GET16(&fData->fTrie, c, category);
+
+            // Check the dictionary bit in the character's category.
+            //    Counter is only used by dictionary based iterators (subclasses).
+            //    Chars that need to be handled by a dictionary have a flag bit set
+            //    in their category values.
+            //
+            if ((category & 0x4000) != 0)  {
+                fDictionaryCharCount++;
+                //  And off the dictionary flag bit.
+                category &= ~0x4000;
+            }
+        }
+
+        #ifdef RBBI_DEBUG
+            if (fTrace) {
+                RBBIDebugPrintf("             %4ld   ", utext_getNativeIndex(fText));
+                if (0x20<=c && c<0x7f) {
+                    RBBIDebugPrintf("\"%c\"  ", c);
+                } else {
+                    RBBIDebugPrintf("%5x  ", c);
+                }
+                RBBIDebugPrintf("%3d  %3d\n", state, category);
+            }
+        #endif
+
+        // State Transition - move machine to its next state
+        //
+        state = row->fNextState[category];
+        row = (RBBIStateTableRow *)
+            // (statetable->fTableData + (statetable->fRowLen * state));
+            (tableData + tableRowLen * state);
+
+
+        if (row->fAccepting == -1) {
+            // Match found, common case.
+            if (mode != RBBI_START) {
+                result = (int32_t)UTEXT_GETNATIVEINDEX(fText);
+            }
+            fLastRuleStatusIndex = row->fTagIdx;   // Remember the break status (tag) values.
+        }
+
+        if (row->fLookAhead != 0) {
+            if (lookaheadStatus != 0
+                && row->fAccepting == lookaheadStatus) {
+                // Lookahead match is completed.  
+                result               = lookaheadResult;
+                fLastRuleStatusIndex = lookaheadTagIdx;
+                lookaheadStatus      = 0;
+                // TODO:  make a standalone hard break in a rule work.
+                if (lookAheadHardBreak) {
+                    UTEXT_SETNATIVEINDEX(fText, result);
+                    return result;
+                }
+                // Look-ahead completed, but other rules may match further.  Continue on
+                //  TODO:  junk this feature?  I don't think it's used anywhwere.
+                goto continueOn;
+            }
+
+            int32_t  r = (int32_t)UTEXT_GETNATIVEINDEX(fText);
+            lookaheadResult = r;
+            lookaheadStatus = row->fLookAhead;
+            lookaheadTagIdx = row->fTagIdx;
+            goto continueOn;
+        }
+
+
+        if (row->fAccepting != 0) {
+            // Because this is an accepting state, any in-progress look-ahead match
+            //   is no longer relavant.  Clear out the pending lookahead status.
+            lookaheadStatus = 0;           // clear out any pending look-ahead match.
+        }
+
+continueOn:
+        if (state == STOP_STATE) {
+            // This is the normal exit from the lookup state machine.
+            // We have advanced through the string until it is certain that no
+            //   longer match is possible, no matter what characters follow.
+            break;
+        }
+        
+        // Advance to the next character.  
+        // If this is a beginning-of-input loop iteration, don't advance
+        //    the input position.  The next iteration will be processing the
+        //    first real input character.
+        if (mode == RBBI_RUN) {
+            c = UTEXT_NEXT32(fText);
+        } else {
+            if (mode == RBBI_START) {
+                mode = RBBI_RUN;
+            }
+        }
+
+
+    }
+
+    // The state machine is done.  Check whether it found a match...
+
+    // If the iterator failed to advance in the match engine, force it ahead by one.
+    //   (This really indicates a defect in the break rules.  They should always match
+    //    at least one character.)
+    if (result == initialPosition) {
+        UTEXT_SETNATIVEINDEX(fText, initialPosition);
+        UTEXT_NEXT32(fText);
+        result = (int32_t)UTEXT_GETNATIVEINDEX(fText);
+    }
+
+    // Leave the iterator at our result position.
+    UTEXT_SETNATIVEINDEX(fText, result);
+    #ifdef RBBI_DEBUG
+        if (fTrace) {
+            RBBIDebugPrintf("result = %d\n\n", result);
+        }
+    #endif
+    return result;
+}
+
+
+
+//-----------------------------------------------------------------------------------
+//
+//  handlePrevious()
+//
+//      Iterate backwards, according to the logic of the reverse rules.
+//      This version handles the exact style backwards rules.
+//
+//      The logic of this function is very similar to handleNext(), above.
+//
+//-----------------------------------------------------------------------------------
+int32_t RuleBasedBreakIterator::handlePrevious(const RBBIStateTable *statetable) {
+    int32_t             state;
+    int16_t             category        = 0;
+    RBBIRunMode         mode;
+    RBBIStateTableRow  *row;
+    UChar32             c;
+    int32_t             lookaheadStatus = 0;
+    int32_t             result          = 0;
+    int32_t             initialPosition = 0;
+    int32_t             lookaheadResult = 0;
+    UBool               lookAheadHardBreak = (statetable->fFlags & RBBI_LOOKAHEAD_HARD_BREAK) != 0;
+
+    #ifdef RBBI_DEBUG
+        if (fTrace) {
+            RBBIDebugPuts("Handle Previous   pos   char  state category");
+        }
+    #endif
+
+    // handlePrevious() never gets the rule status.
+    // Flag the status as invalid; if the user ever asks for status, we will need
+    // to back up, then re-find the break position using handleNext(), which does
+    // get the status value.
+    fLastStatusIndexValid = FALSE;
+    fLastRuleStatusIndex = 0;
+
+    // if we're already at the start of the text, return DONE.
+    if (fText == NULL || fData == NULL || UTEXT_GETNATIVEINDEX(fText)==0) {
+        return BreakIterator::DONE;
+    }
+
+    //  Set up the starting char.
+    initialPosition = (int32_t)UTEXT_GETNATIVEINDEX(fText);
+    result          = initialPosition;
+    c               = UTEXT_PREVIOUS32(fText);
+
+    //  Set the initial state for the state machine
+    state = START_STATE;
+    row = (RBBIStateTableRow *)
+            (statetable->fTableData + (statetable->fRowLen * state));
+    category = 3;
+    mode     = RBBI_RUN;
+    if (statetable->fFlags & RBBI_BOF_REQUIRED) {
+        category = 2;
+        mode     = RBBI_START;
+    }
+
+
+    // loop until we reach the start of the text or transition to state 0
+    //
+    for (;;) {
+        if (c == U_SENTINEL) {
+            // Reached end of input string.
+            if (mode == RBBI_END || 
+                *(int32_t *)fData->fHeader->fFormatVersion == 1 ) {
+                // We have already run the loop one last time with the 
+                //   character set to the psueudo {eof} value.  Now it is time
+                //   to unconditionally bail out.
+                //  (Or we have an old format binary rule file that does not support {eof}.)
+                if (lookaheadResult < result) {
+                    // We ran off the end of the string with a pending look-ahead match.
+                    // Treat this as if the look-ahead condition had been met, and return
+                    //  the match at the / position from the look-ahead rule.
+                    result               = lookaheadResult;
+                    lookaheadStatus = 0;
+                } else if (result == initialPosition) {
+                    // Ran off start, no match found.
+                    // move one index one (towards the start, since we are doing a previous())
+                    UTEXT_SETNATIVEINDEX(fText, initialPosition);
+                    UTEXT_PREVIOUS32(fText);   // TODO:  shouldn't be necessary.  We're already at beginning.  Check.
+                }
+                break;
+            }
+            // Run the loop one last time with the fake end-of-input character category.
+            mode = RBBI_END;
+            category = 1;
+        }
+
+        //
+        // Get the char category.  An incoming category of 1 or 2 means that
+        //      we are preset for doing the beginning or end of input, and
+        //      that we shouldn't get a category from an actual text input character.
+        //
+        if (mode == RBBI_RUN) {
+            // look up the current character's character category, which tells us
+            // which column in the state table to look at.
+            // Note:  the 16 in UTRIE_GET16 refers to the size of the data being returned,
+            //        not the size of the character going in, which is a UChar32.
+            //
+            UTRIE_GET16(&fData->fTrie, c, category);
+
+            // Check the dictionary bit in the character's category.
+            //    Counter is only used by dictionary based iterators (subclasses).
+            //    Chars that need to be handled by a dictionary have a flag bit set
+            //    in their category values.
+            //
+            if ((category & 0x4000) != 0)  {
+                fDictionaryCharCount++;
+                //  And off the dictionary flag bit.
+                category &= ~0x4000;
+            }
+        }
+
+        #ifdef RBBI_DEBUG
+            if (fTrace) {
+                RBBIDebugPrintf("             %4d   ", (int32_t)utext_getNativeIndex(fText));
+                if (0x20<=c && c<0x7f) {
+                    RBBIDebugPrintf("\"%c\"  ", c);
+                } else {
+                    RBBIDebugPrintf("%5x  ", c);
+                }
+                RBBIDebugPrintf("%3d  %3d\n", state, category);
+            }
+        #endif
+
+        // State Transition - move machine to its next state
+        //
+        state = row->fNextState[category];
+        row = (RBBIStateTableRow *)
+            (statetable->fTableData + (statetable->fRowLen * state));
+
+        if (row->fAccepting == -1) {
+            // Match found, common case.
+            result = (int32_t)UTEXT_GETNATIVEINDEX(fText);
+        }
+
+        if (row->fLookAhead != 0) {
+            if (lookaheadStatus != 0
+                && row->fAccepting == lookaheadStatus) {
+                // Lookahead match is completed.  
+                result               = lookaheadResult;
+                lookaheadStatus      = 0;
+                // TODO:  make a standalone hard break in a rule work.
+                if (lookAheadHardBreak) {
+                    UTEXT_SETNATIVEINDEX(fText, result);
+                    return result;
+                }
+                // Look-ahead completed, but other rules may match further.  Continue on
+                //  TODO:  junk this feature?  I don't think it's used anywhwere.
+                goto continueOn;
+            }
+
+            int32_t  r = (int32_t)UTEXT_GETNATIVEINDEX(fText);
+            lookaheadResult = r;
+            lookaheadStatus = row->fLookAhead;
+            goto continueOn;
+        }
+
+
+        if (row->fAccepting != 0) {
+            // Because this is an accepting state, any in-progress look-ahead match
+            //   is no longer relavant.  Clear out the pending lookahead status.
+            lookaheadStatus = 0;    
+        }
+
+continueOn:
+        if (state == STOP_STATE) {
+            // This is the normal exit from the lookup state machine.
+            // We have advanced through the string until it is certain that no
+            //   longer match is possible, no matter what characters follow.
+            break;
+        }
+
+        // Move (backwards) to the next character to process.  
+        // If this is a beginning-of-input loop iteration, don't advance
+        //    the input position.  The next iteration will be processing the
+        //    first real input character.
+        if (mode == RBBI_RUN) {
+            c = UTEXT_PREVIOUS32(fText);
+        } else {            
+            if (mode == RBBI_START) {
+                mode = RBBI_RUN;
+            }
+        }
+    }
+
+    // The state machine is done.  Check whether it found a match...
+
+    // If the iterator failed to advance in the match engine, force it ahead by one.
+    //   (This really indicates a defect in the break rules.  They should always match
+    //    at least one character.)
+    if (result == initialPosition) {
+        UTEXT_SETNATIVEINDEX(fText, initialPosition);
+        UTEXT_PREVIOUS32(fText);
+        result = (int32_t)UTEXT_GETNATIVEINDEX(fText);
+    }
+
+    // Leave the iterator at our result position.
+    UTEXT_SETNATIVEINDEX(fText, result);
+    #ifdef RBBI_DEBUG
+        if (fTrace) {
+            RBBIDebugPrintf("result = %d\n\n", result);
+        }
+    #endif
+    return result;
+}
+
+
+void
+RuleBasedBreakIterator::reset()
+{
+    if (fCachedBreakPositions) {
+        uprv_free(fCachedBreakPositions);
+    }
+    fCachedBreakPositions = NULL;
+    fNumCachedBreakPositions = 0;
+    fDictionaryCharCount = 0;
+    fPositionInCache = 0;
+}
+
+
+
+//-------------------------------------------------------------------------------
+//
+//   getRuleStatus()   Return the break rule tag associated with the current
+//                     iterator position.  If the iterator arrived at its current
+//                     position by iterating forwards, the value will have been
+//                     cached by the handleNext() function.
+//
+//                     If no cached status value is available, the status is
+//                     found by doing a previous() followed by a next(), which
+//                     leaves the iterator where it started, and computes the
+//                     status while doing the next().
+//
+//-------------------------------------------------------------------------------
+void RuleBasedBreakIterator::makeRuleStatusValid() {
+    if (fLastStatusIndexValid == FALSE) {
+        //  No cached status is available.
+        if (fText == NULL || current() == 0) {
+            //  At start of text, or there is no text.  Status is always zero.
+            fLastRuleStatusIndex = 0;
+            fLastStatusIndexValid = TRUE;
+        } else {
+            //  Not at start of text.  Find status the tedious way.
+            int32_t pa = current();
+            previous();
+            if (fNumCachedBreakPositions > 0) {
+                reset();                // Blow off the dictionary cache
+            }
+            int32_t pb = next();
+            if (pa != pb) {
+                // note: the if (pa != pb) test is here only to eliminate warnings for
+                //       unused local variables on gcc.  Logically, it isn't needed.
+                U_ASSERT(pa == pb);
+            }
+        }
+    }
+    U_ASSERT(fLastRuleStatusIndex >= 0  &&  fLastRuleStatusIndex < fData->fStatusMaxIdx);
+}
+
+
+int32_t  RuleBasedBreakIterator::getRuleStatus() const {
+    RuleBasedBreakIterator *nonConstThis  = (RuleBasedBreakIterator *)this;
+    nonConstThis->makeRuleStatusValid();
+
+    // fLastRuleStatusIndex indexes to the start of the appropriate status record
+    //                                                 (the number of status values.)
+    //   This function returns the last (largest) of the array of status values.
+    int32_t  idx = fLastRuleStatusIndex + fData->fRuleStatusTable[fLastRuleStatusIndex];
+    int32_t  tagVal = fData->fRuleStatusTable[idx];
+
+    return tagVal;
+}
+
+
+
+
+int32_t RuleBasedBreakIterator::getRuleStatusVec(
+             int32_t *fillInVec, int32_t capacity, UErrorCode &status)
+{
+    if (U_FAILURE(status)) {
+        return 0;
+    }
+
+    RuleBasedBreakIterator *nonConstThis  = (RuleBasedBreakIterator *)this;
+    nonConstThis->makeRuleStatusValid();
+    int32_t  numVals = fData->fRuleStatusTable[fLastRuleStatusIndex];
+    int32_t  numValsToCopy = numVals;
+    if (numVals > capacity) {
+        status = U_BUFFER_OVERFLOW_ERROR;
+        numValsToCopy = capacity;
+    }
+    int i;
+    for (i=0; i<numValsToCopy; i++) {
+        fillInVec[i] = fData->fRuleStatusTable[fLastRuleStatusIndex + i + 1];
+    }
+    return numVals;
+}
+
+
+
+//-------------------------------------------------------------------------------
+//
+//   getBinaryRules        Access to the compiled form of the rules,
+//                         for use by build system tools that save the data
+//                         for standard iterator types.
+//
+//-------------------------------------------------------------------------------
+const uint8_t  *RuleBasedBreakIterator::getBinaryRules(uint32_t &length) {
+    const uint8_t  *retPtr = NULL;
+    length = 0;
+
+    if (fData != NULL) {
+        retPtr = (const uint8_t *)fData->fHeader;
+        length = fData->fHeader->fLength;
+    }
+    return retPtr;
+}
+
+
+
+
+//-------------------------------------------------------------------------------
+//
+//  BufferClone       TODO:  In my (Andy) opinion, this function should be deprecated.
+//                    Saving one heap allocation isn't worth the trouble.
+//                    Cloning shouldn't be done in tight loops, and
+//                    making the clone copy involves other heap operations anyway.
+//                    And the application code for correctly dealing with buffer
+//                    size problems and the eventual object destruction is ugly.
+//
+//-------------------------------------------------------------------------------
+BreakIterator *  RuleBasedBreakIterator::createBufferClone(void *stackBuffer,
+                                   int32_t &bufferSize,
+                                   UErrorCode &status)
+{
+    if (U_FAILURE(status)){
+        return NULL;
+    }
+
+    //
+    //  If user buffer size is zero this is a preflight operation to
+    //    obtain the needed buffer size, allowing for worst case misalignment.
+    //
+    if (bufferSize == 0) {
+        bufferSize = sizeof(RuleBasedBreakIterator) + U_ALIGNMENT_OFFSET_UP(0);
+        return NULL;
+    }
+
+
+    //
+    //  Check the alignment and size of the user supplied buffer.
+    //  Allocate heap memory if the user supplied memory is insufficient.
+    //
+    char    *buf   = (char *)stackBuffer;
+    uint32_t s      = bufferSize;
+
+    if (stackBuffer == NULL) {
+        s = 0;   // Ignore size, force allocation if user didn't give us a buffer.
+    }
+    if (U_ALIGNMENT_OFFSET(stackBuffer) != 0) {
+        uint32_t offsetUp = (uint32_t)U_ALIGNMENT_OFFSET_UP(buf);
+        s   -= offsetUp;
+        buf += offsetUp;
+    }
+    if (s < sizeof(RuleBasedBreakIterator)) {
+        // Not enough room in the caller-supplied buffer.
+        // Do a plain-vanilla heap based clone and return that, along with
+        //   a warning that the clone was allocated.
+        RuleBasedBreakIterator *clonedBI = new RuleBasedBreakIterator(*this);
+        if (clonedBI == 0) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+        } else {
+            status = U_SAFECLONE_ALLOCATED_WARNING;
+        }
+        return clonedBI;
+    }
+
+    //
+    //  Clone the source BI into the caller-supplied buffer.
+    //    TODO:  using an overloaded operator new to directly initialize the
+    //           copy in the user's buffer would be better, but it doesn't seem
+    //           to get along with namespaces.  Investigate why.
+    //
+    //           The memcpy is only safe with an empty (default constructed)
+    //           break iterator.  Use on others can screw up reference counts
+    //           to data.  memcpy-ing objects is not really a good idea...
+    //
+    RuleBasedBreakIterator localIter;        // Empty break iterator, source for memcpy
+    RuleBasedBreakIterator *clone = (RuleBasedBreakIterator *)buf;
+    uprv_memcpy(clone, &localIter, sizeof(RuleBasedBreakIterator)); // init C++ gorp, BreakIterator base class part
+    clone->init();                // Init RuleBasedBreakIterator part, (user default constructor)
+    *clone = *this;               // clone = the real BI we want.
+    clone->fBufferClone = TRUE;   // Flag to prevent deleting storage on close (From C code)
+
+    return clone;
+}
+
+
+//-------------------------------------------------------------------------------
+//
+//  isDictionaryChar      Return true if the category lookup for this char
+//                        indicates that it is in the set of dictionary lookup
+//                        chars.
+//
+//                        This function is intended for use by dictionary based
+//                        break iterators.
+//
+//-------------------------------------------------------------------------------
+/*UBool RuleBasedBreakIterator::isDictionaryChar(UChar32   c) {
+    if (fData == NULL) {
+        return FALSE;
+    }
+    uint16_t category;
+    UTRIE_GET16(&fData->fTrie, c, category);
+    return (category & 0x4000) != 0;
+}*/
+
+
+//-------------------------------------------------------------------------------
+//
+//  checkDictionary       This function handles all processing of characters in
+//                        the "dictionary" set. It will determine the appropriate
+//                        course of action, and possibly set up a cache in the
+//                        process.
+//
+//-------------------------------------------------------------------------------
+int32_t RuleBasedBreakIterator::checkDictionary(int32_t startPos,
+                            int32_t endPos,
+                            UBool reverse) {
+    // Reset the old break cache first.
+    uint32_t dictionaryCount = fDictionaryCharCount;
+    reset();
+
+    if (dictionaryCount <= 1 || (endPos - startPos) <= 1) {
+        return (reverse ? startPos : endPos);
+    }
+    
+    // Starting from the starting point, scan towards the proposed result,
+    // looking for the first dictionary character (which may be the one
+    // we're on, if we're starting in the middle of a range).
+    utext_setNativeIndex(fText, reverse ? endPos : startPos);
+    if (reverse) {
+        UTEXT_PREVIOUS32(fText);
+    }
+    
+    int32_t rangeStart = startPos;
+    int32_t rangeEnd = endPos;
+
+    uint16_t    category;
+    int32_t     current;
+    UErrorCode  status = U_ZERO_ERROR;
+    UStack      breaks(status);
+    int32_t     foundBreakCount = 0;
+    UChar32     c = utext_current32(fText);
+
+    UTRIE_GET16(&fData->fTrie, c, category);
+    
+    // Is the character we're starting on a dictionary character? If so, we
+    // need to back up to include the entire run; otherwise the results of
+    // the break algorithm will differ depending on where we start. Since
+    // the result is cached and there is typically a non-dictionary break
+    // within a small number of words, there should be little performance impact.
+    if (category & 0x4000) {
+        if (reverse) {
+            do {
+                utext_next32(fText);          // TODO:  recast to work directly with postincrement.
+                c = utext_current32(fText);
+                UTRIE_GET16(&fData->fTrie, c, category);
+            } while (c != U_SENTINEL && (category & 0x4000));
+            // Back up to the last dictionary character
+            rangeEnd = (int32_t)UTEXT_GETNATIVEINDEX(fText);
+            if (c == U_SENTINEL) {
+                // c = fText->last32();
+                //   TODO:  why was this if needed?
+                c = UTEXT_PREVIOUS32(fText);
+            }
+            else {
+                c = UTEXT_PREVIOUS32(fText);
+            }
+        }
+        else {
+            do {
+                c = UTEXT_PREVIOUS32(fText);
+                UTRIE_GET16(&fData->fTrie, c, category);
+            }
+            while (c != U_SENTINEL && (category & 0x4000));
+            // Back up to the last dictionary character
+            if (c == U_SENTINEL) {
+                // c = fText->first32();
+                c = utext_current32(fText);
+            }
+            else {
+                utext_next32(fText);
+                c = utext_current32(fText);
+            }
+            rangeStart = (int32_t)UTEXT_GETNATIVEINDEX(fText);;
+        }
+        UTRIE_GET16(&fData->fTrie, c, category);
+    }
+    
+    // Loop through the text, looking for ranges of dictionary characters.
+    // For each span, find the appropriate break engine, and ask it to find
+    // any breaks within the span.
+    // Note: we always do this in the forward direction, so that the break
+    // cache is built in the right order.
+    if (reverse) {
+        utext_setNativeIndex(fText, rangeStart);
+        c = utext_current32(fText);
+        UTRIE_GET16(&fData->fTrie, c, category);
+    }
+    while(U_SUCCESS(status)) {
+        while((current = (int32_t)UTEXT_GETNATIVEINDEX(fText)) < rangeEnd && (category & 0x4000) == 0) {
+            utext_next32(fText);           // TODO:  tweak for post-increment operation
+            c = utext_current32(fText);
+            UTRIE_GET16(&fData->fTrie, c, category);
+        }
+        if (current >= rangeEnd) {
+            break;
+        }
+        
+        // We now have a dictionary character. Get the appropriate language object
+        // to deal with it.
+        const LanguageBreakEngine *lbe = getLanguageBreakEngine(c);
+        
+        // Ask the language object if there are any breaks. It will leave the text
+        // pointer on the other side of its range, ready to search for the next one.
+        if (lbe != NULL) {
+            foundBreakCount += lbe->findBreaks(fText, rangeStart, rangeEnd, FALSE, fBreakType, breaks);
+        }
+        
+        // Reload the loop variables for the next go-round
+        c = utext_current32(fText);
+        UTRIE_GET16(&fData->fTrie, c, category);
+    }
+    
+    // If we found breaks, build a new break cache. The first and last entries must
+    // be the original starting and ending position.
+    if (foundBreakCount > 0) {
+        int32_t totalBreaks = foundBreakCount;
+        if (startPos < breaks.elementAti(0)) {
+            totalBreaks += 1;
+        }
+        if (endPos > breaks.peeki()) {
+            totalBreaks += 1;
+        }
+        fCachedBreakPositions = (int32_t *)uprv_malloc(totalBreaks * sizeof(int32_t));
+        if (fCachedBreakPositions != NULL) {
+            int32_t out = 0;
+            fNumCachedBreakPositions = totalBreaks;
+            if (startPos < breaks.elementAti(0)) {
+                fCachedBreakPositions[out++] = startPos;
+            }
+            for (int32_t i = 0; i < foundBreakCount; ++i) {
+                fCachedBreakPositions[out++] = breaks.elementAti(i);
+            }
+            if (endPos > fCachedBreakPositions[out-1]) {
+                fCachedBreakPositions[out] = endPos;
+            }
+            // If there are breaks, then by definition, we are replacing the original
+            // proposed break by one of the breaks we found. Use following() and
+            // preceding() to do the work. They should never recurse in this case.
+            if (reverse) {
+                return preceding(endPos - 1);
+            }
+            else {
+                return following(startPos);
+            }
+        }
+        // If the allocation failed, just fall through to the "no breaks found" case.
+    }
+
+    // If we get here, there were no language-based breaks. Set the text pointer
+    // to the original proposed break.
+    utext_setNativeIndex(fText, reverse ? startPos : endPos);
+    return (reverse ? startPos : endPos);
+}
+
+U_NAMESPACE_END
+
+// defined in ucln_cmn.h
+
+static U_NAMESPACE_QUALIFIER UStack *gLanguageBreakFactories = NULL;
+
+/**
+ * Release all static memory held by breakiterator.  
+ */
+U_CDECL_BEGIN
+static UBool U_CALLCONV breakiterator_cleanup_dict(void) {
+    if (gLanguageBreakFactories) {
+        delete gLanguageBreakFactories;
+        gLanguageBreakFactories = NULL;
+    }
+    return TRUE;
+}
+U_CDECL_END
+
+U_CDECL_BEGIN
+static void U_CALLCONV _deleteFactory(void *obj) {
+    delete (U_NAMESPACE_QUALIFIER LanguageBreakFactory *) obj;
+}
+U_CDECL_END
+U_NAMESPACE_BEGIN
+
+static const LanguageBreakEngine*
+getLanguageBreakEngineFromFactory(UChar32 c, int32_t breakType)
+{
+    UBool       needsInit;
+    UErrorCode  status = U_ZERO_ERROR;
+    UMTX_CHECK(NULL, (UBool)(gLanguageBreakFactories == NULL), needsInit);
+    
+    if (needsInit) {
+        UStack  *factories = new UStack(_deleteFactory, NULL, status);
+        if (factories != NULL && U_SUCCESS(status)) {
+            ICULanguageBreakFactory *builtIn = new ICULanguageBreakFactory(status);
+            factories->push(builtIn, status);
+#ifdef U_LOCAL_SERVICE_HOOK
+            LanguageBreakFactory *extra = (LanguageBreakFactory *)uprv_svc_hook("languageBreakFactory", &status);
+            if (extra != NULL) {
+                factories->push(extra, status);
+            }
+#endif
+        }
+        umtx_lock(NULL);
+        if (gLanguageBreakFactories == NULL) {
+            gLanguageBreakFactories = factories;
+            factories = NULL;
+            ucln_common_registerCleanup(UCLN_COMMON_BREAKITERATOR_DICT, breakiterator_cleanup_dict);
+        }
+        umtx_unlock(NULL);
+        delete factories;
+    }
+    
+    if (gLanguageBreakFactories == NULL) {
+        return NULL;
+    }
+    
+    int32_t i = gLanguageBreakFactories->size();
+    const LanguageBreakEngine *lbe = NULL;
+    while (--i >= 0) {
+        LanguageBreakFactory *factory = (LanguageBreakFactory *)(gLanguageBreakFactories->elementAt(i));
+        lbe = factory->getEngineFor(c, breakType);
+        if (lbe != NULL) {
+            break;
+        }
+    }
+    return lbe;
+}
+
+
+//-------------------------------------------------------------------------------
+//
+//  getLanguageBreakEngine  Find an appropriate LanguageBreakEngine for the
+//                          the characer c.
+//
+//-------------------------------------------------------------------------------
+const LanguageBreakEngine *
+RuleBasedBreakIterator::getLanguageBreakEngine(UChar32 c) {
+    const LanguageBreakEngine *lbe = NULL;
+    UErrorCode status = U_ZERO_ERROR;
+    
+    if (fLanguageBreakEngines == NULL) {
+        fLanguageBreakEngines = new UStack(status);
+        if (fLanguageBreakEngines == NULL || U_FAILURE(status)) {
+            delete fLanguageBreakEngines;
+            fLanguageBreakEngines = 0;
+            return NULL;
+        }
+    }
+    
+    int32_t i = fLanguageBreakEngines->size();
+    while (--i >= 0) {
+        lbe = (const LanguageBreakEngine *)(fLanguageBreakEngines->elementAt(i));
+        if (lbe->handles(c, fBreakType)) {
+            return lbe;
+        }
+    }
+    
+    // No existing dictionary took the character. See if a factory wants to
+    // give us a new LanguageBreakEngine for this character.
+    lbe = getLanguageBreakEngineFromFactory(c, fBreakType);
+    
+    // If we got one, use it and push it on our stack.
+    if (lbe != NULL) {
+        fLanguageBreakEngines->push((void *)lbe, status);
+        // Even if we can't remember it, we can keep looking it up, so
+        // return it even if the push fails.
+        return lbe;
+    }
+    
+    // No engine is forthcoming for this character. Add it to the
+    // reject set. Create the reject break engine if needed.
+    if (fUnhandledBreakEngine == NULL) {
+        fUnhandledBreakEngine = new UnhandledEngine(status);
+        if (U_SUCCESS(status) && fUnhandledBreakEngine == NULL) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+        }
+        // Put it last so that scripts for which we have an engine get tried
+        // first.
+        fLanguageBreakEngines->insertElementAt(fUnhandledBreakEngine, 0, status);
+        // If we can't insert it, or creation failed, get rid of it
+        if (U_FAILURE(status)) {
+            delete fUnhandledBreakEngine;
+            fUnhandledBreakEngine = 0;
+            return NULL;
+        }
+    }
+    
+    // Tell the reject engine about the character; at its discretion, it may
+    // add more than just the one character.
+    fUnhandledBreakEngine->handleCharacter(c, fBreakType);
+        
+    return fUnhandledBreakEngine;
+}
+
+
+
+/*int32_t RuleBasedBreakIterator::getBreakType() const {
+    return fBreakType;
+}*/
+
+void RuleBasedBreakIterator::setBreakType(int32_t type) {
+    fBreakType = type;
+    reset();
+}
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/icu/source/common/rbbicst.pl b/icu/source/common/rbbicst.pl
new file mode 100644
index 0000000..98b06cb
--- /dev/null
+++ b/icu/source/common/rbbicst.pl
@@ -0,0 +1,453 @@
+#**************************************************************************
+#   Copyright (C) 2002-2005 International Business Machines Corporation   *
+#   and others. All rights reserved.                                      *
+#**************************************************************************
+#
+#  rbbicst   Compile the RBBI rule paser state table data into initialized C data.
+#            Usage:
+#                   cd icu/source/common
+#                   perl rbbicst.pl    < rbbirpt.txt > rbbirpt.h
+#                   perl rbbicst.pl -j < rbbirpt.txt > RBBIRuleParseTable.java
+#
+#             The output file, rbbrpt.h, is included by some of the .cpp rbbi
+#             implementation files.   This perl script is NOT run as part
+#             of a normal ICU build.  It is run by hand when needed, and the
+#             rbbirpt.h generated file is put back into cvs.
+#
+#             See rbbirpt.txt for a description of the input format for this script.
+#
+
+if ($ARGV[0] eq "-j") {
+    $javaOutput = 1;
+    shift @ARGV;
+}
+
+
+$num_states = 1;     # Always the state number for the line being compiled.
+$line_num  = 0;      # The line number in the input file.
+
+$states{"pop"} = 255;    # Add the "pop"  to the list of defined state names.
+                         # This prevents any state from being labelled with "pop",
+                         #  and resolves references to "pop" in the next state field.
+
+line_loop: while (<>) {
+    chomp();
+    $line = $_;
+    @fields = split();
+    $line_num++;
+
+    # Remove # comments, which are any fields beginning with a #, plus all
+    #  that follow on the line.
+    for ($i=0; $i<@fields; $i++) {
+        if ($fields[$i] =~ /^#/) {
+            @fields = @fields[0 .. $i-1];
+            last;
+        }
+    }
+    # ignore blank lines, and those with no fields left after stripping comments..
+    if (@fields == 0) {
+        next;
+    }
+
+    #
+    # State Label:  handling.
+    #    Does the first token end with a ":"?  If so, it's the name  of a state.
+    #    Put in a hash, together with the current state number,
+    #        so that we can later look up the number from the name.
+    #
+    if (@fields[0] =~ /.*:$/) {
+        $state_name = @fields[0];
+        $state_name =~ s/://;        # strip off the colon from the state name.
+
+        if ($states{$state_name} != 0) {
+            print "  rbbicst: at line $line-num duplicate definition of state $state_name\n";
+        }
+        $states{$state_name} = $num_states;
+        $stateNames[$num_states] = $state_name;
+
+        # if the label was the only thing on this line, go on to the next line,
+        # otherwise assume that a state definition is on the same line and fall through.
+        if (@fields == 1) {
+            next line_loop;
+        }
+        shift @fields;                       # shift off label field in preparation
+                                             #  for handling the rest of the line.
+    }
+
+    #
+    # State Transition line.
+    #   syntax is this,
+    #       character   [n]  target-state  [^push-state]  [function-name]
+    #   where
+    #      [something]   is an optional something
+    #      character     is either a single quoted character e.g. '['
+    #                       or a name of a character class, e.g. white_space
+    #
+
+    $state_line_num[$num_states] = $line_num;   # remember line number with each state
+                                                #  so we can make better error messages later.
+    #
+    # First field, character class or literal character for this transition.
+    #
+    if ($fields[0] =~ /^'.'$/) {
+        # We've got a quoted literal character.
+        $state_literal_chars[$num_states] = $fields[0];
+        $state_literal_chars[$num_states] =~ s/'//g;
+    } else {
+        # We've got the name of a character class.
+        $state_char_class[$num_states] = $fields[0];
+        if ($fields[0] =~ /[\W]/) {
+            print "  rbbicsts:  at line $line_num, bad character literal or character class name.\n";
+            print "     scanning $fields[0]\n";
+            exit(-1);
+        }
+    }
+    shift @fields;
+
+    #
+    # do the 'n' flag
+    #
+    $state_flag[$num_states] = $javaOutput? "false" : "FALSE";
+    if ($fields[0] eq "n") {
+        $state_flag[$num_states] = $javaOutput? "true": "TRUE";
+        shift @fields;
+    }
+
+    #
+    # do the destination state.
+    #
+    $state_dest_state[$num_states] = $fields[0];
+    if ($fields[0] eq "") {
+        print "  rbbicsts:  at line $line_num, destination state missing.\n";
+        exit(-1);
+    }
+    shift @fields;
+
+    #
+    # do the push state, if present.
+    #
+    if ($fields[0] =~ /^\^/) {
+        $fields[0] =~ s/^\^//;
+        $state_push_state[$num_states] = $fields[0];
+        if ($fields[0] eq "" ) {
+            print "  rbbicsts:  at line $line_num, expected state after ^ (no spaces).\n";
+            exit(-1);
+        }
+        shift @fields;
+    }
+
+    #
+    # Lastly, do the optional action name.
+    #
+    if ($fields[0] ne "") {
+        $state_func_name[$num_states] = $fields[0];
+        shift @fields;
+    }
+
+    #
+    #  There should be no fields left on the line at this point.
+    #
+    if (@fields > 0) {
+       print "  rbbicsts:  at line $line_num, unexpected extra stuff on input line.\n";
+       print "     scanning $fields[0]\n";
+   }
+   $num_states++;
+}
+
+#
+# We've read in the whole file, now go back and output the
+#   C source code for the state transition table.
+#
+# We read all states first, before writing anything,  so that the state numbers
+# for the destination states are all available to be written.
+#
+
+#
+# Make hashes for the names of the character classes and
+#      for the names of the actions that appeared.
+#
+for ($state=1; $state < $num_states; $state++) {
+    if ($state_char_class[$state] ne "") {
+        if ($charClasses{$state_char_class[$state]} == 0) {
+            $charClasses{$state_char_class[$state]} = 1;
+        }
+    }
+    if ($state_func_name[$state] eq "") {
+        $state_func_name[$state] = "doNOP";
+    }
+    if ($actions{$state_action_name[$state]} == 0) {
+        $actions{$state_func_name[$state]} = 1;
+    }
+}
+
+#
+# Check that all of the destination states have been defined
+#
+#
+$states{"exit"} = 0;              # Predefined state name, terminates state machine.
+for ($state=1; $state<$num_states; $state++) {
+   if ($states{$state_dest_state[$state]} == 0 && $state_dest_state[$state] ne "exit") {
+       print "Error at line $state_line_num[$state]: target state \"$state_dest_state[$state]\" is not defined.\n";
+       $errors++;
+   }
+   if ($state_push_state[$state] ne "" && $states{$state_push_state[$state]} == 0) {
+       print "Error at line $state_line_num[$state]: target state \"$state_push_state[$state]\" is not defined.\n";
+       $errors++;
+   }
+}
+
+die if ($errors>0);
+
+#
+# Assign numbers to each of the character classes classes  used.
+#   Sets are numbered from 128 - 250
+#   The values 0-127 in the state table are used for matching
+#     individual ASCII characters (the only thing that can appear in the rules.)
+#   The "set" names appearing in the code below (default, etc.)  need special
+#     handling because they do not correspond to a normal set of characters,
+#     but trigger special handling by code in the state machine.
+#
+$i = 128;
+foreach $setName (sort keys %charClasses) {
+    if ($setName eq "default") {
+        $charClasses{$setName} = 255;}
+    elsif ($setName eq "escaped") {
+        $charClasses{$setName} = 254;}
+    elsif ($setName eq "escapedP") {
+        $charClasses{$setName} = 253;}
+    elsif ($setName eq "eof") {
+        $charClasses{$setName} = 252;}
+    else {
+        # Normal (single) character class.  Number them.
+        $charClasses{$setName} = $i;
+        $i++;
+    }
+}
+
+
+my ($sec, $min, $hour, , $day, $mon, $year, $wday, $yday, $isdst) = localtime;
+$year += 1900;
+
+if ($javaOutput) {
+    print "/*\n";
+    print " *******************************************************************************\n";
+    print " * Copyright (C) 2003-$year,\n";
+    print " * International Business Machines Corporation and others. All Rights Reserved.\n";
+    print " *******************************************************************************\n";
+    print " */\n";
+    print " \n";
+    print "package com.ibm.icu.text;\n";
+    print " \n";
+    print "/**\n";
+    print " * Generated Java File.  Do not edit by hand.\n";
+    print " * This file contains the state table for the ICU Rule Based Break Iterator\n";
+    print " * rule parser.\n";
+    print " * It is generated by the Perl script \"rbbicst.pl\" from\n";
+    print " * the rule parser state definitions file \"rbbirpt.txt\".\n";
+    print " * \@internal \n";
+    print " *\n";
+    print " */\n";
+
+    print "class RBBIRuleParseTable\n";
+    print "{\n";
+
+     #
+    # Emit the constants for the actions to be performed.
+    #
+    $n = 1;
+    foreach $act (sort keys %actions) {
+        print "     static final short $act = $n;\n";
+        $n++;
+    }
+    print " \n";
+    
+    #
+    # Emit constants for char class names
+    #
+    foreach $setName (sort keys %charClasses) {
+       print "     static final short kRuleSet_$setName = $charClasses{$setName};\n";
+    }
+    print "\n\n";
+    
+    
+    print "   static class RBBIRuleTableElement { \n";
+    print "      short      fAction; \n";
+    print "      short      fCharClass; \n";
+    print "      short      fNextState; \n";
+    print "      short      fPushState; \n";
+    print "      boolean    fNextChar;  \n";
+    print "      String     fStateName; \n";
+    print "      RBBIRuleTableElement(short a, int cc, int ns, int ps, boolean nc, String sn) {  \n";
+    print "      fAction = a; \n";
+    print "      fCharClass = (short)cc; \n";
+    print "      fNextState = (short)ns; \n";
+    print "      fPushState = (short)ps; \n";
+    print "      fNextChar  = nc; \n";
+    print "      fStateName = sn; \n";
+    print "   } \n";
+    print "   }; \n";
+    print "  \n";
+    
+    
+    print "    static RBBIRuleTableElement[] gRuleParseStateTable = { \n ";
+    print "      new RBBIRuleTableElement(doNOP, 0, 0,0,  true,   null )     //  0 \n";  #output the unused state 0. 
+    for ($state=1; $state < $num_states; $state++) {
+        print "     , new RBBIRuleTableElement($state_func_name[$state],";
+        if ($state_literal_chars[$state] ne "") {
+            $c = $state_literal_chars[$state];
+            print("'$c', "); 
+        }else {
+            print " $charClasses{$state_char_class[$state]},";
+        }
+        print " $states{$state_dest_state[$state]},";
+ 
+        # The push-state field is optional.  If omitted, fill field with a zero, which flags
+        #   the state machine that there is no push state.
+        if ($state_push_state[$state] eq "") {
+            print "0, ";
+        } else {
+            print " $states{$state_push_state[$state]},";
+        }
+        print " $state_flag[$state], ";
+ 
+        # if this is the first row of the table for this state, put out the state name.
+        if ($stateNames[$state] ne "") {
+            print "  \"$stateNames[$state]\") ";
+        } else {
+            print "  null ) ";
+        }
+            
+        # Put out a comment showing the number (index) of this state row,
+        print "    //  $state ";
+        print "\n";
+    }
+    print " };\n";
+
+    print "}; \n";
+    
+}
+else
+{
+    #
+    #  C++ Output ...
+    #
+
+
+    print "//---------------------------------------------------------------------------------\n";
+    print "//\n";
+    print "// Generated Header File.  Do not edit by hand.\n";
+    print "//    This file contains the state table for the ICU Rule Based Break Iterator\n";
+    print "//    rule parser.\n";
+    print "//    It is generated by the Perl script \"rbbicst.pl\" from\n";
+    print "//    the rule parser state definitions file \"rbbirpt.txt\".\n";
+    print "//\n";
+    print "//   Copyright (C) 2002-$year International Business Machines Corporation \n";
+    print "//   and others. All rights reserved.  \n";
+    print "//\n";
+    print "//---------------------------------------------------------------------------------\n";
+    print "#ifndef RBBIRPT_H\n";
+    print "#define RBBIRPT_H\n";
+    print "\n";
+    print "U_NAMESPACE_BEGIN\n";
+
+    #
+    # Emit the constants for indicies of Unicode Sets
+    #   Define one constant for each of the character classes encountered.
+    #   At the same time, store the index corresponding to the set name back into hash.
+    #
+    print "//\n";
+    print "// Character classes for RBBI rule scanning.\n";
+    print "//\n";
+    foreach $setName (sort keys %charClasses) {
+        if ($charClasses{$setName} < 250) {
+           # Normal character class.
+           print "    static const uint8_t kRuleSet_$setName = $charClasses{$setName};\n";
+        }
+    }
+    print "\n\n";
+
+    #
+    # Emit the enum for the actions to be performed.
+    #
+    print "enum RBBI_RuleParseAction {\n";
+    foreach $act (sort keys %actions) {
+        print "    $act,\n";
+    }
+    print "    rbbiLastAction};\n\n";
+
+    #
+    # Emit the struct definition for transtion table elements.
+    #
+    print "//-------------------------------------------------------------------------------\n";
+    print "//\n";
+    print "//  RBBIRuleTableEl    represents the structure of a row in the transition table\n";
+    print "//                     for the rule parser state machine.\n";
+    print "//-------------------------------------------------------------------------------\n";
+    print "struct RBBIRuleTableEl {\n";
+    print "    RBBI_RuleParseAction          fAction;\n";
+    print "    uint8_t                       fCharClass;       // 0-127:    an individual ASCII character\n";
+    print "                                                    // 128-255:  character class index\n";
+    print "    uint8_t                       fNextState;       // 0-250:    normal next-stat numbers\n";
+    print "                                                    // 255:      pop next-state from stack.\n";
+    print "    uint8_t                       fPushState;\n";
+    print "    UBool                         fNextChar;\n";
+    print "};\n\n";
+
+    #
+    # emit the state transition table
+    #
+    print "static const struct RBBIRuleTableEl gRuleParseStateTable[] = {\n";
+    print "    {doNOP, 0, 0, 0, TRUE}\n";    # State 0 is a dummy.  Real states start with index = 1.
+    for ($state=1; $state < $num_states; $state++) {
+        print "    , {$state_func_name[$state],";
+        if ($state_literal_chars[$state] ne "") {
+            $c = $state_literal_chars[$state];
+            printf(" %d /* $c */,", ord($c));   #  use numeric value, so EBCDIC machines are ok.
+        }else {
+            print " $charClasses{$state_char_class[$state]},";
+        }
+        print " $states{$state_dest_state[$state]},";
+
+        # The push-state field is optional.  If omitted, fill field with a zero, which flags
+        #   the state machine that there is no push state.
+        if ($state_push_state[$state] eq "") {
+            print "0, ";
+        } else {
+            print " $states{$state_push_state[$state]},";
+        }
+        print " $state_flag[$state]} ";
+
+        # Put out a C++ comment showing the number (index) of this state row,
+        #   and, if this is the first row of the table for this state, the state name.
+        print "    //  $state ";
+        if ($stateNames[$state] ne "") {
+            print "     $stateNames[$state]";
+        }
+        print "\n";
+    };
+    print " };\n";
+
+
+    #
+    # emit a mapping array from state numbers to state names.
+    #
+    #    This array is used for producing debugging output from the rule parser.
+    #
+    print "#ifdef RBBI_DEBUG\n";
+    print "static const char * const RBBIRuleStateNames[] = {";
+    for ($state=0; $state<$num_states; $state++) {
+        if ($stateNames[$state] ne "") {
+            print "     \"$stateNames[$state]\",\n";
+        } else {
+            print "    0,\n";
+        }
+    }
+    print "    0};\n";
+    print "#endif\n\n";
+
+    print "U_NAMESPACE_END\n";
+    print "#endif\n";
+}
+
+
+
diff --git a/icu/source/common/rbbidata.cpp b/icu/source/common/rbbidata.cpp
new file mode 100644
index 0000000..442fb3d
--- /dev/null
+++ b/icu/source/common/rbbidata.cpp
@@ -0,0 +1,450 @@
+/*
+***************************************************************************
+*   Copyright (C) 1999-2008 International Business Machines Corporation   *
+*   and others. All rights reserved.                                      *
+***************************************************************************
+*/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/utypes.h"
+#include "rbbidata.h"
+#include "rbbirb.h"
+#include "utrie.h"
+#include "udatamem.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "umutex.h"
+
+#include "uassert.h"
+
+
+//-----------------------------------------------------------------------------------
+//
+//   Trie access folding function.  Copied as-is from properties code in uchar.c
+//
+//-----------------------------------------------------------------------------------
+U_CDECL_BEGIN
+static int32_t U_CALLCONV
+getFoldingOffset(uint32_t data) {
+    /* if bit 15 is set, then the folding offset is in bits 14..0 of the 16-bit trie result */
+    if(data&0x8000) {
+        return (int32_t)(data&0x7fff);
+    } else {
+        return 0;
+    }
+}
+U_CDECL_END
+
+U_NAMESPACE_BEGIN
+
+//-----------------------------------------------------------------------------
+//
+//    Constructors.
+//
+//-----------------------------------------------------------------------------
+RBBIDataWrapper::RBBIDataWrapper(const RBBIDataHeader *data, UErrorCode &status) {
+    init(data, status);
+}
+
+RBBIDataWrapper::RBBIDataWrapper(const RBBIDataHeader *data, enum EDontAdopt, UErrorCode &status) {
+    init(data, status);
+    fDontFreeData = TRUE;
+}
+
+RBBIDataWrapper::RBBIDataWrapper(UDataMemory* udm, UErrorCode &status) {
+    const RBBIDataHeader *d = (const RBBIDataHeader *)
+        // ((char *)&(udm->pHeader->info) + udm->pHeader->info.size);
+        // taking into consideration the padding added in by udata_write
+        ((char *)(udm->pHeader) + udm->pHeader->dataHeader.headerSize);
+    init(d, status);
+    fUDataMem = udm;
+}
+
+//-----------------------------------------------------------------------------
+//
+//    init().   Does most of the work of construction, shared between the
+//              constructors.
+//
+//-----------------------------------------------------------------------------
+void RBBIDataWrapper::init(const RBBIDataHeader *data, UErrorCode &status) {
+    if (U_FAILURE(status)) {
+        return;
+    }
+    fHeader = data;
+    if (fHeader->fMagic != 0xb1a0 || 
+        !(fHeader->fFormatVersion[0] == 3 ||         // ICU 3.4 
+          *(int32_t *)fHeader->fFormatVersion == 1))  // ICU 3.2 and earlier.
+    {
+        status = U_INVALID_FORMAT_ERROR;
+        return;
+    }
+
+    fDontFreeData = FALSE;
+    fUDataMem     = NULL;
+    fReverseTable = NULL;
+    fSafeFwdTable = NULL;
+    fSafeRevTable = NULL;
+    if (data->fFTableLen != 0) {
+        fForwardTable = (RBBIStateTable *)((char *)data + fHeader->fFTable);
+    }
+    if (data->fRTableLen != 0) {
+        fReverseTable = (RBBIStateTable *)((char *)data + fHeader->fRTable);
+    }
+    if (data->fSFTableLen != 0) {
+        fSafeFwdTable = (RBBIStateTable *)((char *)data + fHeader->fSFTable);
+    }
+    if (data->fSRTableLen != 0) {
+        fSafeRevTable = (RBBIStateTable *)((char *)data + fHeader->fSRTable);
+    }
+
+
+    utrie_unserialize(&fTrie,
+                       (uint8_t *)data + fHeader->fTrie,
+                       fHeader->fTrieLen,
+                       &status);
+    if (U_FAILURE(status)) {
+        return;
+    }
+    fTrie.getFoldingOffset=getFoldingOffset;
+
+
+    fRuleSource   = (UChar *)((char *)data + fHeader->fRuleSource);
+    fRuleString.setTo(TRUE, fRuleSource, -1);
+    U_ASSERT(data->fRuleSourceLen > 0);
+
+    fRuleStatusTable = (int32_t *)((char *)data + fHeader->fStatusTable);
+    fStatusMaxIdx    = data->fStatusTableLen / sizeof(int32_t);
+
+    fRefCount = 1;
+
+#ifdef RBBI_DEBUG
+    char *debugEnv = getenv("U_RBBIDEBUG");
+    if (debugEnv && uprv_strstr(debugEnv, "data")) {this->printData();}
+#endif
+}
+
+
+//-----------------------------------------------------------------------------
+//
+//    Destructor.     Don't call this - use removeReference() instead.
+//
+//-----------------------------------------------------------------------------
+RBBIDataWrapper::~RBBIDataWrapper() {
+    U_ASSERT(fRefCount == 0);
+    if (fUDataMem) {
+        udata_close(fUDataMem);
+    } else if (!fDontFreeData) {
+        uprv_free((void *)fHeader);
+    }
+}
+
+
+
+//-----------------------------------------------------------------------------
+//
+//   Operator ==    Consider two RBBIDataWrappers to be equal if they
+//                  refer to the same underlying data.  Although
+//                  the data wrappers are normally shared between
+//                  iterator instances, it's possible to independently
+//                  open the same data twice, and get two instances, which
+//                  should still be ==.
+//
+//-----------------------------------------------------------------------------
+UBool RBBIDataWrapper::operator ==(const RBBIDataWrapper &other) const {
+    if (fHeader == other.fHeader) {
+        return TRUE;
+    }
+    if (fHeader->fLength != other.fHeader->fLength) {
+        return FALSE;
+    }
+    if (uprv_memcmp(fHeader, other.fHeader, fHeader->fLength) == 0) {
+        return TRUE;
+    }
+    return FALSE;
+}
+
+int32_t  RBBIDataWrapper::hashCode() {
+    return fHeader->fFTableLen;
+}
+
+
+
+//-----------------------------------------------------------------------------
+//
+//    Reference Counting.   A single RBBIDataWrapper object is shared among
+//                          however many RulesBasedBreakIterator instances are
+//                          referencing the same data.
+//
+//-----------------------------------------------------------------------------
+void RBBIDataWrapper::removeReference() {
+    if (umtx_atomic_dec(&fRefCount) == 0) {
+        delete this;
+    }
+}
+
+
+RBBIDataWrapper *RBBIDataWrapper::addReference() {
+   umtx_atomic_inc(&fRefCount);
+   return this;
+}
+
+
+
+//-----------------------------------------------------------------------------
+//
+//  getRuleSourceString
+//
+//-----------------------------------------------------------------------------
+const UnicodeString &RBBIDataWrapper::getRuleSourceString() const {
+    return fRuleString;
+}
+
+
+//-----------------------------------------------------------------------------
+//
+//  print   -  debugging function to dump the runtime data tables.
+//
+//-----------------------------------------------------------------------------
+#ifdef RBBI_DEBUG
+void  RBBIDataWrapper::printTable(const char *heading, const RBBIStateTable *table) {
+    uint32_t   c;
+    uint32_t   s;
+
+    RBBIDebugPrintf("   %s\n", heading);
+
+    RBBIDebugPrintf("State |  Acc  LA TagIx");
+    for (c=0; c<fHeader->fCatCount; c++) {RBBIDebugPrintf("%3d ", c);}
+    RBBIDebugPrintf("\n------|---------------"); for (c=0;c<fHeader->fCatCount; c++) {
+        RBBIDebugPrintf("----");
+    }
+    RBBIDebugPrintf("\n");
+
+    if (table == NULL) {
+        RBBIDebugPrintf("         N U L L   T A B L E\n\n");
+        return;
+    }
+    for (s=0; s<table->fNumStates; s++) {
+        RBBIStateTableRow *row = (RBBIStateTableRow *)
+                                  (table->fTableData + (table->fRowLen * s));
+        RBBIDebugPrintf("%4d  |  %3d %3d %3d ", s, row->fAccepting, row->fLookAhead, row->fTagIdx);
+        for (c=0; c<fHeader->fCatCount; c++)  {
+            RBBIDebugPrintf("%3d ", row->fNextState[c]);
+        }
+        RBBIDebugPrintf("\n");
+    }
+    RBBIDebugPrintf("\n");
+}
+#endif
+
+
+#ifdef RBBI_DEBUG
+void  RBBIDataWrapper::printData() {
+    RBBIDebugPrintf("RBBI Data at %p\n", (void *)fHeader);
+    RBBIDebugPrintf("   Version = {%d %d %d %d}\n", fHeader->fFormatVersion[0], fHeader->fFormatVersion[1],
+                                                    fHeader->fFormatVersion[2], fHeader->fFormatVersion[3]);
+    RBBIDebugPrintf("   total length of data  = %d\n", fHeader->fLength);
+    RBBIDebugPrintf("   number of character categories = %d\n\n", fHeader->fCatCount);
+
+    printTable("Forward State Transition Table", fForwardTable);
+    printTable("Reverse State Transition Table", fReverseTable);
+    printTable("Safe Forward State Transition Table", fSafeFwdTable);
+    printTable("Safe Reverse State Transition Table", fSafeRevTable);
+
+    RBBIDebugPrintf("\nOrignal Rules source:\n");
+    for (int32_t c=0; fRuleSource[c] != 0; c++) {
+        RBBIDebugPrintf("%c", fRuleSource[c]);
+    }
+    RBBIDebugPrintf("\n\n");
+}
+#endif
+
+
+U_NAMESPACE_END
+U_NAMESPACE_USE
+
+//-----------------------------------------------------------------------------
+//
+//  ubrk_swap   -  byte swap and char encoding swap of RBBI data
+//
+//-----------------------------------------------------------------------------
+
+U_CAPI int32_t U_EXPORT2
+ubrk_swap(const UDataSwapper *ds, const void *inData, int32_t length, void *outData,
+           UErrorCode *status) {
+
+    if (status == NULL || U_FAILURE(*status)) {
+        return 0;
+    }
+    if(ds==NULL || inData==NULL || length<-1 || (length>0 && outData==NULL)) {
+        *status=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    //
+    //  Check that the data header is for for break data.
+    //    (Header contents are defined in genbrk.cpp)
+    //
+    const UDataInfo *pInfo = (const UDataInfo *)((const char *)inData+4);
+    if(!(  pInfo->dataFormat[0]==0x42 &&   /* dataFormat="Brk " */
+           pInfo->dataFormat[1]==0x72 &&
+           pInfo->dataFormat[2]==0x6b &&
+           pInfo->dataFormat[3]==0x20 &&
+           pInfo->formatVersion[0]==3  )) {
+        udata_printError(ds, "ubrk_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized\n",
+                         pInfo->dataFormat[0], pInfo->dataFormat[1],
+                         pInfo->dataFormat[2], pInfo->dataFormat[3],
+                         pInfo->formatVersion[0]);
+        *status=U_UNSUPPORTED_ERROR;
+        return 0;
+    }
+
+    //
+    // Swap the data header.  (This is the generic ICU Data Header, not the RBBI Specific
+    //                         RBBIDataHeader).  This swap also conveniently gets us
+    //                         the size of the ICU d.h., which lets us locate the start
+    //                         of the RBBI specific data.
+    //
+    int32_t headerSize=udata_swapDataHeader(ds, inData, length, outData, status);
+
+
+    //
+    // Get the RRBI Data Header, and check that it appears to be OK.
+    //
+    //    Note:  ICU 3.2 and earlier, RBBIDataHeader::fDataFormat was actually 
+    //           an int32_t with a value of 1.  Starting with ICU 3.4,
+    //           RBBI's fDataFormat matches the dataFormat field from the
+    //           UDataInfo header, four int8_t bytes.  The value is {3,1,0,0}
+    //
+    const uint8_t  *inBytes =(const uint8_t *)inData+headerSize;
+    RBBIDataHeader *rbbiDH = (RBBIDataHeader *)inBytes;
+    UBool           formatVersionOne = ds->readUInt32(*(int32_t *)rbbiDH->fFormatVersion) == 1;
+    if (ds->readUInt32(rbbiDH->fMagic)   != 0xb1a0 ||
+        !(formatVersionOne || rbbiDH->fFormatVersion[0] == 3)   ||
+        ds->readUInt32(rbbiDH->fLength)  <  sizeof(RBBIDataHeader)) 
+    {
+        udata_printError(ds, "ubrk_swap(): RBBI Data header is invalid.\n");
+        *status=U_UNSUPPORTED_ERROR;
+        return 0;
+    }
+
+    //
+    // Prefight operation?  Just return the size
+    //
+    int32_t breakDataLength = ds->readUInt32(rbbiDH->fLength);
+    int32_t totalSize = headerSize + breakDataLength;
+    if (length < 0) {
+        return totalSize;
+    }
+
+    //
+    // Check that length passed in is consistent with length from RBBI data header.
+    //
+    if (length < totalSize) {
+        udata_printError(ds, "ubrk_swap(): too few bytes (%d after ICU Data header) for break data.\n",
+                            breakDataLength);
+        *status=U_INDEX_OUTOFBOUNDS_ERROR;
+        return 0;
+        }
+
+
+    //
+    // Swap the Data.  Do the data itself first, then the RBBI Data Header, because
+    //                 we need to reference the header to locate the data, and an
+    //                 inplace swap of the header leaves it unusable.
+    //
+    uint8_t         *outBytes = (uint8_t *)outData + headerSize;
+    RBBIDataHeader  *outputDH = (RBBIDataHeader *)outBytes;
+
+    int32_t   tableStartOffset;
+    int32_t   tableLength;
+
+    //
+    // If not swapping in place, zero out the output buffer before starting.
+    //    Individual tables and other data items within are aligned to 8 byte boundaries
+    //    when originally created.  Any unused space between items needs to be zero.
+    //
+    if (inBytes != outBytes) {
+        uprv_memset(outBytes, 0, breakDataLength);
+    }
+
+    //
+    // Each state table begins with several 32 bit fields.  Calculate the size
+    //   in bytes of these.
+    //
+    int32_t         topSize = offsetof(RBBIStateTable, fTableData);
+
+    // Forward state table.  
+    tableStartOffset = ds->readUInt32(rbbiDH->fFTable);
+    tableLength      = ds->readUInt32(rbbiDH->fFTableLen);
+
+    if (tableLength > 0) {
+        ds->swapArray32(ds, inBytes+tableStartOffset, topSize, 
+                            outBytes+tableStartOffset, status);
+        ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
+                            outBytes+tableStartOffset+topSize, status);
+    }
+    
+    // Reverse state table.  Same layout as forward table, above.
+    tableStartOffset = ds->readUInt32(rbbiDH->fRTable);
+    tableLength      = ds->readUInt32(rbbiDH->fRTableLen);
+
+    if (tableLength > 0) {
+        ds->swapArray32(ds, inBytes+tableStartOffset, topSize, 
+                            outBytes+tableStartOffset, status);
+        ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
+                            outBytes+tableStartOffset+topSize, status);
+    }
+
+    // Safe Forward state table.  Same layout as forward table, above.
+    tableStartOffset = ds->readUInt32(rbbiDH->fSFTable);
+    tableLength      = ds->readUInt32(rbbiDH->fSFTableLen);
+
+    if (tableLength > 0) {
+        ds->swapArray32(ds, inBytes+tableStartOffset, topSize, 
+                            outBytes+tableStartOffset, status);
+        ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
+                            outBytes+tableStartOffset+topSize, status);
+    }
+
+    // Safe Reverse state table.  Same layout as forward table, above.
+    tableStartOffset = ds->readUInt32(rbbiDH->fSRTable);
+    tableLength      = ds->readUInt32(rbbiDH->fSRTableLen);
+
+    if (tableLength > 0) {
+        ds->swapArray32(ds, inBytes+tableStartOffset, topSize, 
+                            outBytes+tableStartOffset, status);
+        ds->swapArray16(ds, inBytes+tableStartOffset+topSize, tableLength-topSize,
+                            outBytes+tableStartOffset+topSize, status);
+    }
+
+    // Trie table for character categories
+    utrie_swap(ds, inBytes+ds->readUInt32(rbbiDH->fTrie), ds->readUInt32(rbbiDH->fTrieLen),
+                            outBytes+ds->readUInt32(rbbiDH->fTrie), status);
+
+    // Source Rules Text.  It's UChar data
+    ds->swapArray16(ds, inBytes+ds->readUInt32(rbbiDH->fRuleSource), ds->readUInt32(rbbiDH->fRuleSourceLen),
+                        outBytes+ds->readUInt32(rbbiDH->fRuleSource), status);
+
+    // Table of rule status values.  It's all int_32 values
+    ds->swapArray32(ds, inBytes+ds->readUInt32(rbbiDH->fStatusTable), ds->readUInt32(rbbiDH->fStatusTableLen),
+                        outBytes+ds->readUInt32(rbbiDH->fStatusTable), status);
+
+    // And, last, the header.
+    //   For the old version one format, the entire header consists of int32_t values.
+    //   For the newer formats, the fDataFormat field is an array of four bytes.
+    //   Swap the whole thing as int32_t, then, for the newer format, re-swap the one field.
+    //
+    ds->swapArray32(ds, inBytes, sizeof(RBBIDataHeader), outBytes, status);
+    if (formatVersionOne == FALSE) {
+        ds->swapArray32(ds, outputDH->fFormatVersion, 4, outputDH->fFormatVersion, status);
+    }
+
+
+    return totalSize;
+}
+
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/icu/source/common/rbbidata.h b/icu/source/common/rbbidata.h
new file mode 100644
index 0000000..ee6aa48
--- /dev/null
+++ b/icu/source/common/rbbidata.h
@@ -0,0 +1,198 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 1999-2005,2008 International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  rbbidata.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   RBBI data formats  Includes
+*
+*                          Structs that describes the format of the Binary RBBI data,
+*                          as it is stored in ICU's data file.
+*
+*      RBBIDataWrapper  -  Instances of this class sit between the
+*                          raw data structs and the RulesBasedBreakIterator objects
+*                          that are created by applications.  The wrapper class
+*                          provides reference counting for the underlying data,
+*                          and direct pointers to data that would not otherwise
+*                          be accessible without ugly pointer arithmetic.  The
+*                          wrapper does not attempt to provide any higher level
+*                          abstractions for the data itself.
+*
+*                          There will be only one instance of RBBIDataWrapper for any
+*                          set of RBBI run time data being shared by instances
+*                          (clones) of RulesBasedBreakIterator.
+*/
+
+#ifndef __RBBIDATA_H__
+#define __RBBIDATA_H__
+
+#include "unicode/utypes.h"
+#include "unicode/udata.h"
+#include "udataswp.h"
+
+/**
+ * Swap RBBI data. See udataswp.h.
+ * @internal
+ */
+U_CAPI int32_t U_EXPORT2
+ubrk_swap(const UDataSwapper *ds,
+          const void *inData, int32_t length, void *outData,
+          UErrorCode *pErrorCode);
+
+#ifdef XP_CPLUSPLUS
+
+#include "unicode/uobject.h"
+#include "unicode/unistr.h"
+#include "utrie.h"
+
+U_NAMESPACE_BEGIN
+
+/*  
+ *   The following structs map exactly onto the raw data from ICU common data file. 
+ */
+struct RBBIDataHeader {
+    uint32_t         fMagic;           /*  == 0xbla0                                               */
+    uint8_t          fFormatVersion[4]; /* Data Format.  Same as the value in struct UDataInfo      */
+                                       /*   if there is one associated with this data.             */
+                                       /*     (version originates in rbbi, is copied to UDataInfo) */
+                                       /*   For ICU 3.2 and earlier, this field was                */
+                                       /*       uint32_t  fVersion                                 */
+                                       /*   with a value of 1.                                     */
+    uint32_t         fLength;          /*  Total length in bytes of this RBBI Data,                */
+                                       /*      including all sections, not just the header.        */
+    uint32_t         fCatCount;        /*  Number of character categories.                         */
+
+    /*                                                                        */
+    /*  Offsets and sizes of each of the subsections within the RBBI data.    */
+    /*  All offsets are bytes from the start of the RBBIDataHeader.           */
+    /*  All sizes are in bytes.                                               */
+    /*                                                                        */
+    uint32_t         fFTable;         /*  forward state transition table. */
+    uint32_t         fFTableLen;
+    uint32_t         fRTable;         /*  Offset to the reverse state transition table. */
+    uint32_t         fRTableLen;
+    uint32_t         fSFTable;        /*  safe point forward transition table */
+    uint32_t         fSFTableLen;
+    uint32_t         fSRTable;        /*  safe point reverse transition table */
+    uint32_t         fSRTableLen;
+    uint32_t         fTrie;           /*  Offset to Trie data for character categories */
+    uint32_t         fTrieLen;
+    uint32_t         fRuleSource;     /*  Offset to the source for for the break */
+    uint32_t         fRuleSourceLen;  /*    rules.  Stored UChar *. */
+    uint32_t         fStatusTable;    /* Offset to the table of rule status values */
+    uint32_t         fStatusTableLen;
+
+    uint32_t         fReserved[6];    /*  Reserved for expansion */
+
+};
+
+
+
+struct  RBBIStateTableRow {
+    int16_t          fAccepting;    /*  Non-zero if this row is for an accepting state.   */
+                                    /*  Value 0: not an accepting state.                  */
+                                    /*       -1: Unconditional Accepting state.           */
+                                    /*    positive:  Look-ahead match has completed.      */
+                                    /*           Actual boundary position happened earlier */
+                                    /*           Value here == fLookAhead in earlier      */
+                                    /*              state, at actual boundary pos.        */
+    int16_t          fLookAhead;    /*  Non-zero if this row is for a state that          */
+                                    /*    corresponds to a '/' in the rule source.        */
+                                    /*    Value is the same as the fAccepting             */
+                                    /*      value for the rule (which will appear         */
+                                    /*      in a different state.                         */
+    int16_t          fTagIdx;       /*  Non-zero if this row covers a {tagged} position   */
+                                    /*     from a rule.  Value is the index in the        */
+                                    /*     StatusTable of the set of matching             */
+                                    /*     tags (rule status values)                      */
+    int16_t          fReserved;
+    uint16_t         fNextState[2]; /*  Next State, indexed by char category.             */
+                                    /*    Array Size is fNumCols from the                 */
+                                    /*    state table header.                             */
+                                    /*    CAUTION:  see RBBITableBuilder::getTableSize()  */
+                                    /*              before changing anything here.        */
+};
+
+
+struct RBBIStateTable {
+    uint32_t         fNumStates;    /*  Number of states.                                 */
+    uint32_t         fRowLen;       /*  Length of a state table row, in bytes.            */
+    uint32_t         fFlags;        /*  Option Flags for this state table                 */
+    uint32_t         fReserved;     /*  reserved                                          */
+    char             fTableData[4]; /*  First RBBIStateTableRow begins here.              */
+                                    /*    (making it char[] simplifies ugly address       */
+                                    /*     arithmetic for indexing variable length rows.) */
+};
+
+typedef enum {
+    RBBI_LOOKAHEAD_HARD_BREAK = 1,
+    RBBI_BOF_REQUIRED = 2
+} RBBIStateTableFlags;
+
+
+/*                                        */
+/*   The reference counting wrapper class */
+/*                                        */
+class RBBIDataWrapper : public UMemory {
+public:
+    enum EDontAdopt {
+        kDontAdopt
+    };
+    RBBIDataWrapper(const RBBIDataHeader *data, UErrorCode &status);
+    RBBIDataWrapper(const RBBIDataHeader *data, enum EDontAdopt dontAdopt, UErrorCode &status);
+    RBBIDataWrapper(UDataMemory* udm, UErrorCode &status);
+    ~RBBIDataWrapper();
+
+    void                  init(const RBBIDataHeader *data, UErrorCode &status);
+    RBBIDataWrapper      *addReference();
+    void                  removeReference();
+    UBool                 operator ==(const RBBIDataWrapper &other) const;
+    int32_t               hashCode();
+    const UnicodeString  &getRuleSourceString() const;
+#ifdef RBBI_DEBUG
+    void                  printData();
+    void                  printTable(const char *heading, const RBBIStateTable *table);
+#else
+    #define printData()
+    #define printTable(heading, table)
+#endif
+
+    /*                                     */
+    /*   Pointers to items within the data */
+    /*                                     */
+    const RBBIDataHeader     *fHeader;
+    const RBBIStateTable     *fForwardTable;
+    const RBBIStateTable     *fReverseTable;
+    const RBBIStateTable     *fSafeFwdTable;
+    const RBBIStateTable     *fSafeRevTable;
+    const UChar              *fRuleSource;
+    const int32_t            *fRuleStatusTable; 
+
+    /* number of int32_t values in the rule status table.   Used to sanity check indexing */
+    int32_t             fStatusMaxIdx;
+
+    UTrie               fTrie;
+
+private:
+    int32_t             fRefCount;
+    UDataMemory        *fUDataMem;
+    UnicodeString       fRuleString;
+    UBool               fDontFreeData;
+
+    RBBIDataWrapper(const RBBIDataWrapper &other); /*  forbid copying of this class */
+    RBBIDataWrapper &operator=(const RBBIDataWrapper &other); /*  forbid copying of this class */
+};
+
+
+
+U_NAMESPACE_END
+
+#endif /* C++ */
+
+#endif
diff --git a/icu/source/common/rbbinode.cpp b/icu/source/common/rbbinode.cpp
new file mode 100644
index 0000000..49e0ad3
--- /dev/null
+++ b/icu/source/common/rbbinode.cpp
@@ -0,0 +1,358 @@
+/*
+***************************************************************************
+*   Copyright (C) 2002-2008 International Business Machines Corporation   *
+*   and others. All rights reserved.                                      *
+***************************************************************************
+*/
+
+//
+//  File:  rbbinode.cpp
+//
+//         Implementation of class RBBINode, which represents a node in the
+//         tree generated when parsing the Rules Based Break Iterator rules.
+//
+//         This "Class" is actually closer to a struct.
+//         Code using it is expected to directly access fields much of the time.
+//
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/unistr.h"
+#include "unicode/uniset.h"
+#include "unicode/uchar.h"
+#include "unicode/parsepos.h"
+#include "uvector.h"
+
+#include "rbbirb.h"
+#include "rbbinode.h"
+
+#include "uassert.h"
+
+
+U_NAMESPACE_BEGIN
+
+#ifdef RBBI_DEBUG
+static int  gLastSerial = 0;
+#endif
+
+
+//-------------------------------------------------------------------------
+//
+//    Constructor.   Just set the fields to reasonable default values.
+//
+//-------------------------------------------------------------------------
+RBBINode::RBBINode(NodeType t) : UMemory() {
+#ifdef RBBI_DEBUG
+    fSerialNum    = ++gLastSerial;
+#endif
+    fType         = t;
+    fParent       = NULL;
+    fLeftChild    = NULL;
+    fRightChild   = NULL;
+    fInputSet     = NULL;
+    fFirstPos     = 0;
+    fLastPos      = 0;
+    fNullable     = FALSE;
+    fLookAheadEnd = FALSE;
+    fVal          = 0;
+    fPrecedence   = precZero;
+
+    UErrorCode     status = U_ZERO_ERROR;
+    fFirstPosSet  = new UVector(status);  // TODO - get a real status from somewhere
+    fLastPosSet   = new UVector(status);
+    fFollowPos    = new UVector(status);
+    if      (t==opCat)    {fPrecedence = precOpCat;}
+    else if (t==opOr)     {fPrecedence = precOpOr;}
+    else if (t==opStart)  {fPrecedence = precStart;}
+    else if (t==opLParen) {fPrecedence = precLParen;}
+
+}
+
+
+RBBINode::RBBINode(const RBBINode &other) : UMemory(other) {
+#ifdef RBBI_DEBUG
+    fSerialNum   = ++gLastSerial;
+#endif
+    fType        = other.fType;
+    fParent      = NULL;
+    fLeftChild   = NULL;
+    fRightChild  = NULL;
+    fInputSet    = other.fInputSet;
+    fPrecedence  = other.fPrecedence;
+    fText        = other.fText;
+    fFirstPos    = other.fFirstPos;
+    fLastPos     = other.fLastPos;
+    fNullable    = other.fNullable;
+    fVal         = other.fVal;
+    UErrorCode     status = U_ZERO_ERROR;
+    fFirstPosSet = new UVector(status);   // TODO - get a real status from somewhere
+    fLastPosSet  = new UVector(status);
+    fFollowPos   = new UVector(status);
+}
+
+
+//-------------------------------------------------------------------------
+//
+//    Destructor.   Deletes both this node AND any child nodes,
+//                  except in the case of variable reference nodes.  For
+//                  these, the l. child points back to the definition, which
+//                  is common for all references to the variable, meaning
+//                  it can't be deleted here.
+//
+//-------------------------------------------------------------------------
+RBBINode::~RBBINode() {
+    // printf("deleting node %8x   serial %4d\n", this, this->fSerialNum);
+    delete fInputSet;
+    fInputSet = NULL;
+
+    switch (this->fType) {
+    case varRef:
+    case setRef:
+        // for these node types, multiple instances point to the same "children"
+        // Storage ownership of children handled elsewhere.  Don't delete here.
+        break;
+
+    default:
+        delete        fLeftChild;
+        fLeftChild =   NULL;
+        delete        fRightChild;
+        fRightChild = NULL;
+    }
+
+
+    delete fFirstPosSet;
+    delete fLastPosSet;
+    delete fFollowPos;
+
+}
+
+
+//-------------------------------------------------------------------------
+//
+//    cloneTree     Make a copy of the subtree rooted at this node.
+//                  Discard any variable references encountered along the way,
+//                  and replace with copies of the variable's definitions.
+//                  Used to replicate the expression underneath variable
+//                  references in preparation for generating the DFA tables.
+//
+//-------------------------------------------------------------------------
+RBBINode *RBBINode::cloneTree() {
+    RBBINode    *n;
+
+    if (fType == RBBINode::varRef) {
+        // If the current node is a variable reference, skip over it
+        //   and clone the definition of the variable instead.
+        n = fLeftChild->cloneTree();
+    } else if (fType == RBBINode::uset) {
+        n = this;
+    } else {
+        n = new RBBINode(*this);
+        // Check for null pointer.
+        if (n != NULL) {
+            if (fLeftChild != NULL) {
+                n->fLeftChild          = fLeftChild->cloneTree();
+                n->fLeftChild->fParent = n;
+            }
+            if (fRightChild != NULL) {
+                n->fRightChild          = fRightChild->cloneTree();
+                n->fRightChild->fParent = n;
+            }
+        }
+    }
+    return n;
+}
+
+
+
+//-------------------------------------------------------------------------
+//
+//   flattenVariables   Walk a parse tree, replacing any variable
+//                      references with a copy of the variable's definition.
+//                      Aside from variables, the tree is not changed.
+//
+//                      Return the root of the tree.  If the root was not a variable
+//                      reference, it remains unchanged - the root we started with
+//                      is the root we return.  If, however, the root was a variable
+//                      reference, the root of the newly cloned replacement tree will
+//                      be returned, and the original tree deleted.
+//
+//                      This function works by recursively walking the tree
+//                      without doing anything until a variable reference is
+//                      found, then calling cloneTree() at that point.  Any
+//                      nested references are handled by cloneTree(), not here.
+//
+//-------------------------------------------------------------------------
+RBBINode *RBBINode::flattenVariables() {
+    if (fType == varRef) {
+        RBBINode *retNode = fLeftChild->cloneTree();
+        delete this;
+        return retNode;
+    }
+
+    if (fLeftChild != NULL) {
+        fLeftChild = fLeftChild->flattenVariables();
+        fLeftChild->fParent  = this;
+    }
+    if (fRightChild != NULL) {
+        fRightChild = fRightChild->flattenVariables();
+        fRightChild->fParent = this;
+    }
+    return this;
+}
+
+
+//-------------------------------------------------------------------------
+//
+//  flattenSets    Walk the parse tree, replacing any nodes of type setRef
+//                 with a copy of the expression tree for the set.  A set's
+//                 equivalent expression tree is precomputed and saved as
+//                 the left child of the uset node.
+//
+//-------------------------------------------------------------------------
+void RBBINode::flattenSets() {
+    U_ASSERT(fType != setRef);
+
+    if (fLeftChild != NULL) {
+        if (fLeftChild->fType==setRef) {
+            RBBINode *setRefNode = fLeftChild;
+            RBBINode *usetNode   = setRefNode->fLeftChild;
+            RBBINode *replTree   = usetNode->fLeftChild;
+            fLeftChild           = replTree->cloneTree();
+            fLeftChild->fParent  = this;
+            delete setRefNode;
+        } else {
+            fLeftChild->flattenSets();
+        }
+    }
+
+    if (fRightChild != NULL) {
+        if (fRightChild->fType==setRef) {
+            RBBINode *setRefNode = fRightChild;
+            RBBINode *usetNode   = setRefNode->fLeftChild;
+            RBBINode *replTree   = usetNode->fLeftChild;
+            fRightChild           = replTree->cloneTree();
+            fRightChild->fParent  = this;
+            delete setRefNode;
+        } else {
+            fRightChild->flattenSets();
+        }
+    }
+}
+
+
+
+//-------------------------------------------------------------------------
+//
+//   findNodes()     Locate all the nodes of the specified type, starting
+//                   at the specified root.
+//
+//-------------------------------------------------------------------------
+void   RBBINode::findNodes(UVector *dest, RBBINode::NodeType kind, UErrorCode &status) {
+    /* test for buffer overflows */
+    if (U_FAILURE(status)) {
+        return;
+    }
+    if (fType == kind) {
+        dest->addElement(this, status);
+    }
+    if (fLeftChild != NULL) {
+        fLeftChild->findNodes(dest, kind, status);
+    }
+    if (fRightChild != NULL) {
+        fRightChild->findNodes(dest, kind, status);
+    }
+}
+
+
+//-------------------------------------------------------------------------
+//
+//    print.         Print out a single node, for debugging.
+//
+//-------------------------------------------------------------------------
+#ifdef RBBI_DEBUG
+void RBBINode::printNode() {
+    static const char * const nodeTypeNames[] = {
+                "setRef",
+                "uset",
+                "varRef",
+                "leafChar",
+                "lookAhead",
+                "tag",
+                "endMark",
+                "opStart",
+                "opCat",
+                "opOr",
+                "opStar",
+                "opPlus",
+                "opQuestion",
+                "opBreak",
+                "opReverse",
+                "opLParen"
+    };
+
+    if (this==NULL) {
+        RBBIDebugPrintf("%10p", (void *)this);
+    } else {
+        RBBIDebugPrintf("%10p  %12s  %10p  %10p  %10p      %4d     %6d   %d ",
+            (void *)this, nodeTypeNames[fType], (void *)fParent, (void *)fLeftChild, (void *)fRightChild,
+            fSerialNum, fFirstPos, fVal);
+        if (fType == varRef) {
+            RBBI_DEBUG_printUnicodeString(fText);
+        }
+    }
+    RBBIDebugPrintf("\n");
+}
+#endif
+
+
+#ifdef RBBI_DEBUG
+U_CFUNC void RBBI_DEBUG_printUnicodeString(const UnicodeString &s, int minWidth)
+{
+    int i;
+    for (i=0; i<s.length(); i++) {
+        RBBIDebugPrintf("%c", s.charAt(i));
+        // putc(s.charAt(i), stdout);
+    }
+    for (i=s.length(); i<minWidth; i++) {
+        RBBIDebugPrintf(" ");
+    }
+}
+#endif
+
+
+//-------------------------------------------------------------------------
+//
+//    print.         Print out the tree of nodes rooted at "this"
+//
+//-------------------------------------------------------------------------
+#ifdef RBBI_DEBUG
+void RBBINode::printTree(UBool printHeading) {
+    if (printHeading) {
+        RBBIDebugPrintf( "-------------------------------------------------------------------\n"
+                         "    Address       type         Parent   LeftChild  RightChild    serial  position value\n"
+              );
+    }
+    this->printNode();
+    if (this != NULL) {
+        // Only dump the definition under a variable reference if asked to.
+        // Unconditinally dump children of all other node types.
+        if (fType != varRef) {
+            if (fLeftChild != NULL) {
+                fLeftChild->printTree(FALSE);
+            }
+            
+            if (fRightChild != NULL) {
+                fRightChild->printTree(FALSE);
+            }
+        }
+    }
+}
+#endif
+
+
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/icu/source/common/rbbinode.h b/icu/source/common/rbbinode.h
new file mode 100644
index 0000000..0cbf6a7
--- /dev/null
+++ b/icu/source/common/rbbinode.h
@@ -0,0 +1,118 @@
+/********************************************************************
+ * COPYRIGHT:
+ * Copyright (c) 2001-2006, International Business Machines Corporation and
+ * others. All Rights Reserved.
+ ********************************************************************/
+
+#ifndef RBBINODE_H
+#define RBBINODE_H
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+
+//
+//  class RBBINode
+//
+//                    Represents a node in the parse tree generated when reading
+//                    a rule file.
+//
+
+U_NAMESPACE_BEGIN
+
+class    UnicodeSet;
+class    UVector;
+
+class RBBINode : public UMemory {
+    public:
+        enum NodeType {
+            setRef,
+            uset,
+            varRef,
+            leafChar,
+            lookAhead,
+            tag,
+            endMark,
+            opStart,
+            opCat,
+            opOr,
+            opStar,
+            opPlus,
+            opQuestion,
+            opBreak,
+            opReverse,
+            opLParen
+        };
+
+        enum OpPrecedence {      
+            precZero,
+            precStart,
+            precLParen,
+            precOpOr,
+            precOpCat
+        };
+            
+        NodeType      fType;
+        RBBINode      *fParent;
+        RBBINode      *fLeftChild;
+        RBBINode      *fRightChild;
+        UnicodeSet    *fInputSet;           // For uset nodes only.
+        OpPrecedence  fPrecedence;          // For binary ops only.
+        
+        UnicodeString fText;                // Text corresponding to this node.
+                                            //   May be lazily evaluated when (if) needed
+                                            //   for some node types.
+        int           fFirstPos;            // Position in the rule source string of the
+                                            //   first text associated with the node.
+                                            //   If there's a left child, this will be the same
+                                            //   as that child's left pos.
+        int           fLastPos;             //  Last position in the rule source string
+                                            //    of any text associated with this node.
+                                            //    If there's a right child, this will be the same
+                                            //    as that child's last postion.
+
+        UBool         fNullable;            // See Aho.
+        int32_t       fVal;                 // For leafChar nodes, the value.
+                                            //   Values are the character category,
+                                            //   corresponds to columns in the final
+                                            //   state transition table.
+
+        UBool         fLookAheadEnd;        // For endMark nodes, set TRUE if
+                                            //   marking the end of a look-ahead rule.
+
+        UVector       *fFirstPosSet;
+        UVector       *fLastPosSet;         // TODO: rename fFirstPos & fLastPos to avoid confusion.
+        UVector       *fFollowPos;
+
+
+        RBBINode(NodeType t);
+        RBBINode(const RBBINode &other);
+        ~RBBINode();
+        
+        RBBINode    *cloneTree();
+        RBBINode    *flattenVariables();
+        void         flattenSets();
+        void         findNodes(UVector *dest, RBBINode::NodeType kind, UErrorCode &status);
+
+#ifdef RBBI_DEBUG
+        void        printNode();
+        void        printTree(UBool withHeading);
+#endif
+
+    private:
+        RBBINode &operator = (const RBBINode &other); // No defs.
+        UBool operator == (const RBBINode &other);    // Private, so these functions won't accidently be used.
+
+#ifdef RBBI_DEBUG
+        int           fSerialNum;           //  Debugging aids.
+#endif
+};
+
+#ifdef RBBI_DEBUG
+U_CFUNC void 
+RBBI_DEBUG_printUnicodeString(const UnicodeString &s, int minWidth=0);
+#endif
+
+U_NAMESPACE_END
+
+#endif
+
diff --git a/icu/source/common/rbbirb.cpp b/icu/source/common/rbbirb.cpp
new file mode 100644
index 0000000..bbc11cd
--- /dev/null
+++ b/icu/source/common/rbbirb.cpp
@@ -0,0 +1,323 @@
+//
+//  file:  rbbirb.cpp
+//
+//  Copyright (C) 2002-2008, International Business Machines Corporation and others.
+//  All Rights Reserved.
+//
+//  This file contains the RBBIRuleBuilder class implementation.  This is the main class for
+//    building (compiling) break rules into the tables required by the runtime
+//    RBBI engine.
+//
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/brkiter.h"
+#include "unicode/rbbi.h"
+#include "unicode/ubrk.h"
+#include "unicode/unistr.h"
+#include "unicode/uniset.h"
+#include "unicode/uchar.h"
+#include "unicode/uchriter.h"
+#include "unicode/parsepos.h"
+#include "unicode/parseerr.h"
+#include "cmemory.h"
+#include "cstring.h"
+
+#include "rbbirb.h"
+#include "rbbinode.h"
+
+#include "rbbiscan.h"
+#include "rbbisetb.h"
+#include "rbbitblb.h"
+#include "rbbidata.h"
+
+
+U_NAMESPACE_BEGIN
+
+
+//----------------------------------------------------------------------------------------
+//
+//  Constructor.
+//
+//----------------------------------------------------------------------------------------
+RBBIRuleBuilder::RBBIRuleBuilder(const UnicodeString   &rules,
+                                       UParseError     *parseErr,
+                                       UErrorCode      &status)
+ : fRules(rules)
+{
+    fStatus = &status; // status is checked below
+    fParseError = parseErr;
+    fDebugEnv   = NULL;
+#ifdef RBBI_DEBUG
+    fDebugEnv   = getenv("U_RBBIDEBUG");
+#endif
+
+
+    fForwardTree        = NULL;
+    fReverseTree        = NULL;
+    fSafeFwdTree        = NULL;
+    fSafeRevTree        = NULL;
+    fDefaultTree        = &fForwardTree;
+    fForwardTables      = NULL;
+    fReverseTables      = NULL;
+    fSafeFwdTables      = NULL;
+    fSafeRevTables      = NULL;
+    fRuleStatusVals     = NULL;
+    fChainRules         = FALSE;
+    fLBCMNoChain        = FALSE;
+    fLookAheadHardBreak = FALSE;
+    fUSetNodes          = NULL;
+    fRuleStatusVals     = NULL;
+    fScanner            = NULL;
+    fSetBuilder         = NULL;
+    if (parseErr) {
+        uprv_memset(parseErr, 0, sizeof(UParseError));
+    }
+
+    if (U_FAILURE(status)) {
+        return;
+    }
+
+    fUSetNodes          = new UVector(status); // bcos status gets overwritten here
+    fRuleStatusVals     = new UVector(status);
+    fScanner            = new RBBIRuleScanner(this);
+    fSetBuilder         = new RBBISetBuilder(this);
+    if (U_FAILURE(status)) {
+        return;
+    }
+    if(fSetBuilder == 0 || fScanner == 0 || fUSetNodes == 0 || fRuleStatusVals == 0) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+    }
+}
+
+
+
+//----------------------------------------------------------------------------------------
+//
+//  Destructor
+//
+//----------------------------------------------------------------------------------------
+RBBIRuleBuilder::~RBBIRuleBuilder() {
+
+    int        i;
+    for (i=0; ; i++) {
+        RBBINode *n = (RBBINode *)fUSetNodes->elementAt(i);
+        if (n==NULL) {
+            break;
+        }
+        delete n;
+    }
+
+    delete fUSetNodes;
+    delete fSetBuilder;
+    delete fForwardTables;
+    delete fReverseTables;
+    delete fSafeFwdTables;
+    delete fSafeRevTables;
+
+    delete fForwardTree;
+    delete fReverseTree;
+    delete fSafeFwdTree;
+    delete fSafeRevTree;
+    delete fScanner;
+    delete fRuleStatusVals;
+}
+
+
+
+
+
+//----------------------------------------------------------------------------------------
+//
+//   flattenData() -  Collect up the compiled RBBI rule data and put it into
+//                    the format for saving in ICU data files,
+//                    which is also the format needed by the RBBI runtime engine.
+//
+//----------------------------------------------------------------------------------------
+static int32_t align8(int32_t i) {return (i+7) & 0xfffffff8;}
+
+RBBIDataHeader *RBBIRuleBuilder::flattenData() {
+    int32_t    i;
+
+    if (U_FAILURE(*fStatus)) {
+        return NULL;
+    }
+
+    // Remove comments and whitespace from the rules to make it smaller.
+    UnicodeString strippedRules((const UnicodeString&)RBBIRuleScanner::stripRules(fRules));
+
+    // Calculate the size of each section in the data.
+    //   Sizes here are padded up to a multiple of 8 for better memory alignment.
+    //   Sections sizes actually stored in the header are for the actual data
+    //     without the padding.
+    //
+    int32_t headerSize        = align8(sizeof(RBBIDataHeader));
+    int32_t forwardTableSize  = align8(fForwardTables->getTableSize());
+    int32_t reverseTableSize  = align8(fReverseTables->getTableSize());
+    int32_t safeFwdTableSize  = align8(fSafeFwdTables->getTableSize());
+    int32_t safeRevTableSize  = align8(fSafeRevTables->getTableSize());
+    int32_t trieSize          = align8(fSetBuilder->getTrieSize());
+    int32_t statusTableSize   = align8(fRuleStatusVals->size() * sizeof(int32_t));
+    int32_t rulesSize         = align8((strippedRules.length()+1) * sizeof(UChar));
+
+    int32_t         totalSize = headerSize + forwardTableSize + reverseTableSize
+                                + safeFwdTableSize + safeRevTableSize 
+                                + statusTableSize + trieSize + rulesSize;
+
+    RBBIDataHeader  *data     = (RBBIDataHeader *)uprv_malloc(totalSize);
+    if (data == NULL) {
+        *fStatus = U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
+    }
+    uprv_memset(data, 0, totalSize);
+
+
+    data->fMagic            = 0xb1a0;
+    data->fFormatVersion[0] = 3;
+    data->fFormatVersion[1] = 1;
+    data->fFormatVersion[2] = 0;
+    data->fFormatVersion[3] = 0;
+    data->fLength           = totalSize;
+    data->fCatCount         = fSetBuilder->getNumCharCategories();
+
+    data->fFTable        = headerSize;
+    data->fFTableLen     = forwardTableSize;
+    data->fRTable        = data->fFTable  + forwardTableSize;
+    data->fRTableLen     = reverseTableSize;
+    data->fSFTable       = data->fRTable  + reverseTableSize;
+    data->fSFTableLen    = safeFwdTableSize;
+    data->fSRTable       = data->fSFTable + safeFwdTableSize;
+    data->fSRTableLen    = safeRevTableSize;
+
+    data->fTrie          = data->fSRTable + safeRevTableSize;
+    data->fTrieLen       = fSetBuilder->getTrieSize();
+    data->fStatusTable   = data->fTrie    + trieSize;
+    data->fStatusTableLen= statusTableSize;
+    data->fRuleSource    = data->fStatusTable + statusTableSize;
+    data->fRuleSourceLen = strippedRules.length() * sizeof(UChar);
+
+    uprv_memset(data->fReserved, 0, sizeof(data->fReserved));
+
+    fForwardTables->exportTable((uint8_t *)data + data->fFTable);
+    fReverseTables->exportTable((uint8_t *)data + data->fRTable);
+    fSafeFwdTables->exportTable((uint8_t *)data + data->fSFTable);
+    fSafeRevTables->exportTable((uint8_t *)data + data->fSRTable);
+    fSetBuilder->serializeTrie ((uint8_t *)data + data->fTrie);
+
+    int32_t *ruleStatusTable = (int32_t *)((uint8_t *)data + data->fStatusTable);
+    for (i=0; i<fRuleStatusVals->size(); i++) {
+        ruleStatusTable[i] = fRuleStatusVals->elementAti(i);
+    }
+
+    strippedRules.extract((UChar *)((uint8_t *)data+data->fRuleSource), rulesSize/2+1, *fStatus);
+
+    return data;
+}
+
+
+
+
+
+
+//----------------------------------------------------------------------------------------
+//
+//  createRuleBasedBreakIterator    construct from source rules that are passed in
+//                                  in a UnicodeString
+//
+//----------------------------------------------------------------------------------------
+BreakIterator *
+RBBIRuleBuilder::createRuleBasedBreakIterator( const UnicodeString    &rules,
+                                    UParseError      *parseError,
+                                    UErrorCode       &status)
+{
+    // status checked below
+
+    //
+    // Read the input rules, generate a parse tree, symbol table,
+    // and list of all Unicode Sets referenced by the rules.
+    //
+    RBBIRuleBuilder  builder(rules, parseError, status);
+    if (U_FAILURE(status)) { // status checked here bcos build below doesn't
+        return NULL;
+    }
+    builder.fScanner->parse();
+
+    //
+    // UnicodeSet processing.
+    //    Munge the Unicode Sets to create a set of character categories.
+    //    Generate the mapping tables (TRIE) from input 32-bit characters to
+    //    the character categories.
+    //
+    builder.fSetBuilder->build();
+
+
+    //
+    //   Generate the DFA state transition table.
+    //
+    builder.fForwardTables = new RBBITableBuilder(&builder, &builder.fForwardTree);
+    builder.fReverseTables = new RBBITableBuilder(&builder, &builder.fReverseTree);
+    builder.fSafeFwdTables = new RBBITableBuilder(&builder, &builder.fSafeFwdTree);
+    builder.fSafeRevTables = new RBBITableBuilder(&builder, &builder.fSafeRevTree);
+    if (U_SUCCESS(status)
+        && (builder.fForwardTables == NULL || builder.fReverseTables == NULL ||
+            builder.fSafeFwdTables == NULL || builder.fSafeRevTables == NULL)) 
+    {
+        status = U_MEMORY_ALLOCATION_ERROR;
+    }
+    
+    // Before building the tables, check to make sure the status is ok.
+    if (U_FAILURE(status)) {
+    	delete builder.fForwardTables; builder.fForwardTables = NULL;
+    	delete builder.fReverseTables; builder.fReverseTables = NULL;
+    	delete builder.fSafeFwdTables; builder.fSafeFwdTables = NULL;
+    	delete builder.fSafeRevTables; builder.fSafeRevTables = NULL;
+        return NULL;
+    }
+
+    builder.fForwardTables->build();
+    builder.fReverseTables->build();
+    builder.fSafeFwdTables->build();
+    builder.fSafeRevTables->build();
+
+#ifdef RBBI_DEBUG
+    if (builder.fDebugEnv && uprv_strstr(builder.fDebugEnv, "states")) {
+        builder.fForwardTables->printRuleStatusTable();
+    }
+#endif
+
+    //
+    //   Package up the compiled data into a memory image
+    //      in the run-time format.
+    //
+    RBBIDataHeader *data = builder.flattenData(); // returns NULL if error
+    if (U_FAILURE(*builder.fStatus)) {
+        return NULL;
+    }
+
+
+    //
+    //  Clean up the compiler related stuff
+    //
+
+
+    //
+    //  Create a break iterator from the compiled rules.
+    //     (Identical to creation from stored pre-compiled rules)
+    //
+    // status is checked after init in construction.
+    RuleBasedBreakIterator *This = new RuleBasedBreakIterator(data, status);
+    if (U_FAILURE(status)) {
+        delete This;
+        This = NULL;
+    } 
+    else if(This == NULL) { // test for NULL
+        status = U_MEMORY_ALLOCATION_ERROR;
+    }
+    return This;
+}
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/icu/source/common/rbbirb.h b/icu/source/common/rbbirb.h
new file mode 100644
index 0000000..deb9b0e
--- /dev/null
+++ b/icu/source/common/rbbirb.h
@@ -0,0 +1,211 @@
+//
+//  rbbirb.h
+//
+//  Copyright (C) 2002-2008, International Business Machines Corporation and others.
+//  All Rights Reserved.
+//
+//  This file contains declarations for several classes from the
+//    Rule Based Break Iterator rule builder.
+//
+
+
+#ifndef RBBIRB_H
+#define RBBIRB_H
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+#include "unicode/rbbi.h"
+#include "unicode/uniset.h"
+#include "unicode/parseerr.h"
+#include "uhash.h"
+#include "uvector.h"
+#include "unicode/symtable.h"// For UnicodeSet parsing, is the interface that
+                          //    looks up references to $variables within a set.
+
+
+
+U_NAMESPACE_BEGIN
+
+class               RBBIRuleScanner;
+struct              RBBIRuleTableEl;
+class               RBBISetBuilder;
+class               RBBINode;
+class               RBBITableBuilder;
+
+
+
+//--------------------------------------------------------------------------------
+//
+//   RBBISymbolTable.    Implements SymbolTable interface that is used by the
+//                       UnicodeSet parser to resolve references to $variables.
+//
+//--------------------------------------------------------------------------------
+class RBBISymbolTableEntry : public UMemory { // The symbol table hash table contains one
+public:                                       //   of these structs for each entry.
+    RBBISymbolTableEntry();
+    UnicodeString          key;
+    RBBINode               *val;
+    ~RBBISymbolTableEntry();
+
+private:
+    RBBISymbolTableEntry(const RBBISymbolTableEntry &other); // forbid copying of this class
+    RBBISymbolTableEntry &operator=(const RBBISymbolTableEntry &other); // forbid copying of this class
+};
+
+
+class RBBISymbolTable : public UMemory, public SymbolTable {
+private:
+    const UnicodeString      &fRules;
+    UHashtable               *fHashTable;
+    RBBIRuleScanner          *fRuleScanner;
+
+    // These next two fields are part of the mechanism for passing references to
+    //   already-constructed UnicodeSets back to the UnicodeSet constructor
+    //   when the pattern includes $variable references.
+    const UnicodeString      ffffString;      // = "/uffff"
+    UnicodeSet              *fCachedSetLookup;
+
+public:
+    //  API inherited from class SymbolTable
+    virtual const UnicodeString*  lookup(const UnicodeString& s) const;
+    virtual const UnicodeFunctor* lookupMatcher(UChar32 ch) const;
+    virtual UnicodeString parseReference(const UnicodeString& text,
+                                         ParsePosition& pos, int32_t limit) const;
+
+    //  Additional Functions
+    RBBISymbolTable(RBBIRuleScanner *, const UnicodeString &fRules, UErrorCode &status);
+    virtual ~RBBISymbolTable();
+
+    virtual RBBINode *lookupNode(const UnicodeString &key) const;
+    virtual void      addEntry  (const UnicodeString &key, RBBINode *val, UErrorCode &err);
+
+#ifdef RBBI_DEBUG
+    virtual void      rbbiSymtablePrint() const;
+#else
+    // A do-nothing inline function for non-debug builds.  Member funcs can't be empty
+    //  or the call sites won't compile.
+    int32_t fFakeField;
+    #define rbbiSymtablePrint() fFakeField=0; 
+#endif
+
+private:
+    RBBISymbolTable(const RBBISymbolTable &other); // forbid copying of this class
+    RBBISymbolTable &operator=(const RBBISymbolTable &other); // forbid copying of this class
+};
+
+
+//--------------------------------------------------------------------------------
+//
+//  class RBBIRuleBuilder       The top-level class handling RBBI rule compiling.
+//
+//--------------------------------------------------------------------------------
+class RBBIRuleBuilder : public UMemory {
+public:
+
+    //  Create a rule based break iterator from a set of rules.
+    //  This function is the main entry point into the rule builder.  The
+    //   public ICU API for creating RBBIs uses this function to do the actual work.
+    //
+    static BreakIterator * createRuleBasedBreakIterator( const UnicodeString    &rules,
+                                    UParseError      *parseError,
+                                    UErrorCode       &status);
+
+public:
+    // The "public" functions and data members that appear below are accessed
+    //  (and shared) by the various parts that make up the rule builder.  They
+    //  are NOT intended to be accessed by anything outside of the
+    //  rule builder implementation.
+    RBBIRuleBuilder(const UnicodeString  &rules,
+                    UParseError          *parseErr,
+                    UErrorCode           &status
+        );
+
+    virtual    ~RBBIRuleBuilder();
+    char                          *fDebugEnv;        // controls debug trace output
+    UErrorCode                    *fStatus;          // Error reporting.  Keeping status
+    UParseError                   *fParseError;      //   here avoids passing it everywhere.
+    const UnicodeString           &fRules;           // The rule string that we are compiling
+
+    RBBIRuleScanner               *fScanner;         // The scanner.
+    RBBINode                      *fForwardTree;     // The parse trees, generated by the scanner,
+    RBBINode                      *fReverseTree;     //   then manipulated by subsequent steps.
+    RBBINode                      *fSafeFwdTree;
+    RBBINode                      *fSafeRevTree;
+
+    RBBINode                      **fDefaultTree;    // For rules not qualified with a !
+                                                     //   the tree to which they belong to.
+
+    UBool                         fChainRules;       // True for chained Unicode TR style rules.
+                                                     // False for traditional regexp rules.
+
+    UBool                         fLBCMNoChain;      // True:  suppress chaining of rules on
+                                                     //   chars with LineBreak property == CM.
+
+    UBool                         fLookAheadHardBreak;  // True:  Look ahead matches cause an
+                                                     // immediate break, no continuing for the
+                                                     // longest match.
+
+    RBBISetBuilder                *fSetBuilder;      // Set and Character Category builder.
+    UVector                       *fUSetNodes;       // Vector of all uset nodes.
+
+    RBBITableBuilder              *fForwardTables;   // State transition tables
+    RBBITableBuilder              *fReverseTables;
+    RBBITableBuilder              *fSafeFwdTables;
+    RBBITableBuilder              *fSafeRevTables;
+
+    UVector                       *fRuleStatusVals;  // The values that can be returned
+                                                     //   from getRuleStatus().
+
+    RBBIDataHeader                *flattenData();    // Create the flattened (runtime format)
+                                                     // data tables..
+private:
+    RBBIRuleBuilder(const RBBIRuleBuilder &other); // forbid copying of this class
+    RBBIRuleBuilder &operator=(const RBBIRuleBuilder &other); // forbid copying of this class
+};
+
+
+
+
+//----------------------------------------------------------------------------
+//
+//   RBBISetTableEl   is an entry in the hash table of UnicodeSets that have
+//                    been encountered.  The val Node will be of nodetype uset
+//                    and contain pointers to the actual UnicodeSets.
+//                    The Key is the source string for initializing the set.
+//
+//                    The hash table is used to avoid creating duplicate
+//                    unnamed (not $var references) UnicodeSets.
+//
+//                    Memory Management:
+//                       The Hash Table owns these RBBISetTableEl structs and
+//                            the key strings.  It does NOT own the val nodes.
+//
+//----------------------------------------------------------------------------
+struct RBBISetTableEl {
+    UnicodeString *key;
+    RBBINode      *val;
+};
+
+
+//----------------------------------------------------------------------------
+//
+//   RBBIDebugPrintf    Printf equivalent, for debugging output.
+//                      Conditional compilation of the implementation lets us
+//                      get rid of the stdio dependency in environments where it
+//                      is unavailable.
+//
+//----------------------------------------------------------------------------
+#ifdef RBBI_DEBUG
+#include <stdio.h>
+#define RBBIDebugPrintf printf
+#define RBBIDebugPuts puts
+#else
+#undef RBBIDebugPrintf 
+#define RBBIDebugPuts(arg)
+#endif
+
+U_NAMESPACE_END
+#endif
+
+
+
diff --git a/icu/source/common/rbbirpt.h b/icu/source/common/rbbirpt.h
new file mode 100644
index 0000000..deea57b
--- /dev/null
+++ b/icu/source/common/rbbirpt.h
@@ -0,0 +1,275 @@
+//---------------------------------------------------------------------------------
+//
+// Generated Header File.  Do not edit by hand.
+//    This file contains the state table for the ICU Rule Based Break Iterator
+//    rule parser.
+//    It is generated by the Perl script "rbbicst.pl" from
+//    the rule parser state definitions file "rbbirpt.txt".
+//
+//   Copyright (C) 2002-2005 International Business Machines Corporation 
+//   and others. All rights reserved.  
+//
+//---------------------------------------------------------------------------------
+#ifndef RBBIRPT_H
+#define RBBIRPT_H
+
+U_NAMESPACE_BEGIN
+//
+// Character classes for RBBI rule scanning.
+//
+    static const uint8_t kRuleSet_digit_char = 128;
+    static const uint8_t kRuleSet_name_char = 129;
+    static const uint8_t kRuleSet_name_start_char = 130;
+    static const uint8_t kRuleSet_rule_char = 131;
+    static const uint8_t kRuleSet_white_space = 132;
+
+
+enum RBBI_RuleParseAction {
+    doCheckVarDef,
+    doDotAny,
+    doEndAssign,
+    doEndOfRule,
+    doEndVariableName,
+    doExit,
+    doExprCatOperator,
+    doExprFinished,
+    doExprOrOperator,
+    doExprRParen,
+    doExprStart,
+    doLParen,
+    doNOP,
+    doOptionEnd,
+    doOptionStart,
+    doReverseDir,
+    doRuleChar,
+    doRuleError,
+    doRuleErrorAssignExpr,
+    doScanUnicodeSet,
+    doSlash,
+    doStartAssign,
+    doStartTagValue,
+    doStartVariableName,
+    doTagDigit,
+    doTagExpectedError,
+    doTagValue,
+    doUnaryOpPlus,
+    doUnaryOpQuestion,
+    doUnaryOpStar,
+    doVariableNameExpectedErr,
+    rbbiLastAction};
+
+//-------------------------------------------------------------------------------
+//
+//  RBBIRuleTableEl    represents the structure of a row in the transition table
+//                     for the rule parser state machine.
+//-------------------------------------------------------------------------------
+struct RBBIRuleTableEl {
+    RBBI_RuleParseAction          fAction;
+    uint8_t                       fCharClass;       // 0-127:    an individual ASCII character
+                                                    // 128-255:  character class index
+    uint8_t                       fNextState;       // 0-250:    normal next-stat numbers
+                                                    // 255:      pop next-state from stack.
+    uint8_t                       fPushState;
+    UBool                         fNextChar;
+};
+
+static const struct RBBIRuleTableEl gRuleParseStateTable[] = {
+    {doNOP, 0, 0, 0, TRUE}
+    , {doExprStart, 254, 21, 8, FALSE}     //  1      start
+    , {doNOP, 132, 1,0,  TRUE}     //  2 
+    , {doExprStart, 36 /* $ */, 80, 90, FALSE}     //  3 
+    , {doNOP, 33 /* ! */, 11,0,  TRUE}     //  4 
+    , {doNOP, 59 /* ; */, 1,0,  TRUE}     //  5 
+    , {doNOP, 252, 0,0,  FALSE}     //  6 
+    , {doExprStart, 255, 21, 8, FALSE}     //  7 
+    , {doEndOfRule, 59 /* ; */, 1,0,  TRUE}     //  8      break-rule-end
+    , {doNOP, 132, 8,0,  TRUE}     //  9 
+    , {doRuleError, 255, 95,0,  FALSE}     //  10 
+    , {doNOP, 33 /* ! */, 13,0,  TRUE}     //  11      rev-option
+    , {doReverseDir, 255, 20, 8, FALSE}     //  12 
+    , {doOptionStart, 130, 15,0,  TRUE}     //  13      option-scan1
+    , {doRuleError, 255, 95,0,  FALSE}     //  14 
+    , {doNOP, 129, 15,0,  TRUE}     //  15      option-scan2
+    , {doOptionEnd, 255, 17,0,  FALSE}     //  16 
+    , {doNOP, 59 /* ; */, 1,0,  TRUE}     //  17      option-scan3
+    , {doNOP, 132, 17,0,  TRUE}     //  18 
+    , {doRuleError, 255, 95,0,  FALSE}     //  19 
+    , {doExprStart, 255, 21, 8, FALSE}     //  20      reverse-rule
+    , {doRuleChar, 254, 30,0,  TRUE}     //  21      term
+    , {doNOP, 132, 21,0,  TRUE}     //  22 
+    , {doRuleChar, 131, 30,0,  TRUE}     //  23 
+    , {doNOP, 91 /* [ */, 86, 30, FALSE}     //  24 
+    , {doLParen, 40 /* ( */, 21, 30, TRUE}     //  25 
+    , {doNOP, 36 /* $ */, 80, 29, FALSE}     //  26 
+    , {doDotAny, 46 /* . */, 30,0,  TRUE}     //  27 
+    , {doRuleError, 255, 95,0,  FALSE}     //  28 
+    , {doCheckVarDef, 255, 30,0,  FALSE}     //  29      term-var-ref
+    , {doNOP, 132, 30,0,  TRUE}     //  30      expr-mod
+    , {doUnaryOpStar, 42 /* * */, 35,0,  TRUE}     //  31 
+    , {doUnaryOpPlus, 43 /* + */, 35,0,  TRUE}     //  32 
+    , {doUnaryOpQuestion, 63 /* ? */, 35,0,  TRUE}     //  33 
+    , {doNOP, 255, 35,0,  FALSE}     //  34 
+    , {doExprCatOperator, 254, 21,0,  FALSE}     //  35      expr-cont
+    , {doNOP, 132, 35,0,  TRUE}     //  36 
+    , {doExprCatOperator, 131, 21,0,  FALSE}     //  37 
+    , {doExprCatOperator, 91 /* [ */, 21,0,  FALSE}     //  38 
+    , {doExprCatOperator, 40 /* ( */, 21,0,  FALSE}     //  39 
+    , {doExprCatOperator, 36 /* $ */, 21,0,  FALSE}     //  40 
+    , {doExprCatOperator, 46 /* . */, 21,0,  FALSE}     //  41 
+    , {doExprCatOperator, 47 /* / */, 47,0,  FALSE}     //  42 
+    , {doExprCatOperator, 123 /* { */, 59,0,  TRUE}     //  43 
+    , {doExprOrOperator, 124 /* | */, 21,0,  TRUE}     //  44 
+    , {doExprRParen, 41 /* ) */, 255,0,  TRUE}     //  45 
+    , {doExprFinished, 255, 255,0,  FALSE}     //  46 
+    , {doSlash, 47 /* / */, 49,0,  TRUE}     //  47      look-ahead
+    , {doNOP, 255, 95,0,  FALSE}     //  48 
+    , {doExprCatOperator, 254, 21,0,  FALSE}     //  49      expr-cont-no-slash
+    , {doNOP, 132, 35,0,  TRUE}     //  50 
+    , {doExprCatOperator, 131, 21,0,  FALSE}     //  51 
+    , {doExprCatOperator, 91 /* [ */, 21,0,  FALSE}     //  52 
+    , {doExprCatOperator, 40 /* ( */, 21,0,  FALSE}     //  53 
+    , {doExprCatOperator, 36 /* $ */, 21,0,  FALSE}     //  54 
+    , {doExprCatOperator, 46 /* . */, 21,0,  FALSE}     //  55 
+    , {doExprOrOperator, 124 /* | */, 21,0,  TRUE}     //  56 
+    , {doExprRParen, 41 /* ) */, 255,0,  TRUE}     //  57 
+    , {doExprFinished, 255, 255,0,  FALSE}     //  58 
+    , {doNOP, 132, 59,0,  TRUE}     //  59      tag-open
+    , {doStartTagValue, 128, 62,0,  FALSE}     //  60 
+    , {doTagExpectedError, 255, 95,0,  FALSE}     //  61 
+    , {doNOP, 132, 66,0,  TRUE}     //  62      tag-value
+    , {doNOP, 125 /* } */, 66,0,  FALSE}     //  63 
+    , {doTagDigit, 128, 62,0,  TRUE}     //  64 
+    , {doTagExpectedError, 255, 95,0,  FALSE}     //  65 
+    , {doNOP, 132, 66,0,  TRUE}     //  66      tag-close
+    , {doTagValue, 125 /* } */, 69,0,  TRUE}     //  67 
+    , {doTagExpectedError, 255, 95,0,  FALSE}     //  68 
+    , {doExprCatOperator, 254, 21,0,  FALSE}     //  69      expr-cont-no-tag
+    , {doNOP, 132, 69,0,  TRUE}     //  70 
+    , {doExprCatOperator, 131, 21,0,  FALSE}     //  71 
+    , {doExprCatOperator, 91 /* [ */, 21,0,  FALSE}     //  72 
+    , {doExprCatOperator, 40 /* ( */, 21,0,  FALSE}     //  73 
+    , {doExprCatOperator, 36 /* $ */, 21,0,  FALSE}     //  74 
+    , {doExprCatOperator, 46 /* . */, 21,0,  FALSE}     //  75 
+    , {doExprCatOperator, 47 /* / */, 47,0,  FALSE}     //  76 
+    , {doExprOrOperator, 124 /* | */, 21,0,  TRUE}     //  77 
+    , {doExprRParen, 41 /* ) */, 255,0,  TRUE}     //  78 
+    , {doExprFinished, 255, 255,0,  FALSE}     //  79 
+    , {doStartVariableName, 36 /* $ */, 82,0,  TRUE}     //  80      scan-var-name
+    , {doNOP, 255, 95,0,  FALSE}     //  81 
+    , {doNOP, 130, 84,0,  TRUE}     //  82      scan-var-start
+    , {doVariableNameExpectedErr, 255, 95,0,  FALSE}     //  83 
+    , {doNOP, 129, 84,0,  TRUE}     //  84      scan-var-body
+    , {doEndVariableName, 255, 255,0,  FALSE}     //  85 
+    , {doScanUnicodeSet, 91 /* [ */, 255,0,  TRUE}     //  86      scan-unicode-set
+    , {doScanUnicodeSet, 112 /* p */, 255,0,  TRUE}     //  87 
+    , {doScanUnicodeSet, 80 /* P */, 255,0,  TRUE}     //  88 
+    , {doNOP, 255, 95,0,  FALSE}     //  89 
+    , {doNOP, 132, 90,0,  TRUE}     //  90      assign-or-rule
+    , {doStartAssign, 61 /* = */, 21, 93, TRUE}     //  91 
+    , {doNOP, 255, 29, 8, FALSE}     //  92 
+    , {doEndAssign, 59 /* ; */, 1,0,  TRUE}     //  93      assign-end
+    , {doRuleErrorAssignExpr, 255, 95,0,  FALSE}     //  94 
+    , {doExit, 255, 95,0,  TRUE}     //  95      errorDeath
+ };
+#ifdef RBBI_DEBUG
+static const char * const RBBIRuleStateNames[] = {    0,
+     "start",
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+     "break-rule-end",
+    0,
+    0,
+     "rev-option",
+    0,
+     "option-scan1",
+    0,
+     "option-scan2",
+    0,
+     "option-scan3",
+    0,
+    0,
+     "reverse-rule",
+     "term",
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+     "term-var-ref",
+     "expr-mod",
+    0,
+    0,
+    0,
+    0,
+     "expr-cont",
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+     "look-ahead",
+    0,
+     "expr-cont-no-slash",
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+     "tag-open",
+    0,
+    0,
+     "tag-value",
+    0,
+    0,
+    0,
+     "tag-close",
+    0,
+    0,
+     "expr-cont-no-tag",
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+     "scan-var-name",
+    0,
+     "scan-var-start",
+    0,
+     "scan-var-body",
+    0,
+     "scan-unicode-set",
+    0,
+    0,
+    0,
+     "assign-or-rule",
+    0,
+    0,
+     "assign-end",
+    0,
+     "errorDeath",
+    0};
+#endif
+
+U_NAMESPACE_END
+#endif
diff --git a/icu/source/common/rbbirpt.txt b/icu/source/common/rbbirpt.txt
new file mode 100644
index 0000000..8e932a6
--- /dev/null
+++ b/icu/source/common/rbbirpt.txt
@@ -0,0 +1,315 @@
+
+#*****************************************************************************
+#
+#   Copyright (C) 2002-2003, International Business Machines Corporation and others.
+#   All Rights Reserved.
+#
+#*****************************************************************************
+#
+#  file:  rbbirpt.txt
+#  ICU Break Iterator Rule Parser State Table
+#
+#     This state table is used when reading and parsing a set of RBBI rules
+#     The rule parser uses a state machine; the data in this file define the
+#     state transitions that occur for each input character.
+#
+#     *** This file defines the RBBI rule grammar.   This is it.
+#     *** The determination of what is accepted is here.
+#
+#     This file is processed by a perl script "rbbicst.pl" to produce initialized C arrays
+#     that are then built with the rule parser.
+#
+
+#
+# Here is the syntax of the state definitions in this file:
+#
+#
+#StateName:
+#   input-char           n next-state           ^push-state     action    
+#   input-char           n next-state           ^push-state     action    
+#       |                |   |                      |             |
+#       |                |   |                      |             |--- action to be performed by state machine
+#       |                |   |                      |                  See function RBBIRuleScanner::doParseActions()
+#       |                |   |                      |
+#       |                |   |                      |--- Push this named state onto the state stack.
+#       |                |   |                           Later, when next state is specified as "pop",
+#       |                |   |                           the pushed state will become the current state.
+#       |                |   |
+#       |                |   |--- Transition to this state if the current input character matches the input
+#       |                |        character or char class in the left hand column.  "pop" causes the next
+#       |                |        state to be popped from the state stack.
+#       |                |
+#       |                |--- When making the state transition specified on this line, advance to the next
+#       |                     character from the input only if 'n' appears here.
+#       |
+#       |--- Character or named character classes to test for.  If the current character being scanned
+#            matches, peform the actions and go to the state specified on this line.
+#            The input character is tested sequentally, in the order written.  The characters and
+#            character classes tested for do not need to be mutually exclusive.  The first match wins.
+#            
+
+
+
+
+#
+#  start state, scan position is at the beginning of the rules file, or in between two rules.
+#
+start:
+    escaped                term                  ^break-rule-end    doExprStart                       
+    white_space          n start                     
+    '$'                    scan-var-name         ^assign-or-rule    doExprStart
+    '!'                  n rev-option                             
+    ';'                  n start                                                  # ignore empty rules.
+    eof                    exit              
+    default                term                  ^break-rule-end    doExprStart
+    
+#
+#  break-rule-end:  Returned from doing a break-rule expression.
+#
+break-rule-end:
+    ';'	                 n start                                    doEndOfRule
+    white_space          n break-rule-end
+    default                errorDeath                               doRuleError
+     
+
+#
+#   !               We've just scanned a '!', indicating either a !!key word flag or a
+#                   !Reverse rule.
+#
+rev-option:
+    '!'                  n option-scan1   
+    default                reverse-rule           ^break-rule-end   doReverseDir
+    
+option-scan1:
+    name_start_char      n option-scan2                             doOptionStart
+    default                errorDeath                               doRuleError
+    
+option-scan2:
+    name_char            n option-scan2
+    default                option-scan3                             doOptionEnd
+    
+option-scan3:
+    ';'                  n start 
+    white_space          n option-scan3 
+    default                errorDeath                               doRuleError 
+    
+
+reverse-rule:
+    default                term                   ^break-rule-end   doExprStart
+    
+    
+#
+#  term.  Eat through a single rule character, or a composite thing, which
+#         could be a parenthesized expression, a variable name, or a Unicode Set.
+#
+term:
+    escaped              n expr-mod                                 doRuleChar
+    white_space          n term
+    rule_char            n expr-mod                                 doRuleChar
+    '['                    scan-unicode-set      ^expr-mod
+    '('                  n term                  ^expr-mod          doLParen
+    '$'                    scan-var-name         ^term-var-ref
+    '.'                  n expr-mod                                 doDotAny
+    default                errorDeath                               doRuleError
+    
+    
+
+#
+#  term-var-ref   We've just finished scanning a reference to a $variable.
+#                 Check that the variable was defined.
+#                 The variable name scanning is in common with assignment statements,
+#                 so the check can't be done there.
+term-var-ref:
+    default                expr-mod                                 doCheckVarDef
+    
+    
+#
+#   expr-mod      We've just finished scanning a term, now look for the optional
+#                 trailing '*', '?', '+'
+#
+expr-mod:
+    white_space          n  expr-mod
+    '*'                  n  expr-cont                               doUnaryOpStar
+    '+'                  n  expr-cont                               doUnaryOpPlus
+    '?'                  n  expr-cont                               doUnaryOpQuestion
+    default                 expr-cont 
+    
+    
+#
+#  expr-cont      Expression, continuation.  At a point where additional terms are
+#                                            allowed, but not required.
+#
+expr-cont:
+    escaped                 term                                    doExprCatOperator
+    white_space          n  expr-cont
+    rule_char               term                                    doExprCatOperator
+    '['                     term                                    doExprCatOperator
+    '('                     term                                    doExprCatOperator
+    '$'                     term                                    doExprCatOperator
+    '.'                     term                                    doExprCatOperator
+    '/'                     look-ahead                              doExprCatOperator
+    '{'                  n  tag-open                                doExprCatOperator
+    '|'                  n  term                                    doExprOrOperator
+    ')'                  n  pop                                     doExprRParen
+    default                 pop                                     doExprFinished
+    
+
+#
+#   look-ahead    Scanning a '/', which identifies a break point, assuming that the
+#                 remainder of the expression matches.
+#
+#                 Generate a parse tree as if this was a special kind of input symbol
+#                 appearing in an otherwise normal concatenation expression.
+#
+look-ahead:
+    '/'                   n expr-cont-no-slash                      doSlash
+    default                 errorDeath
+
+
+#
+#  expr-cont-no-slash    Expression, continuation.  At a point where additional terms are
+#                                            allowed, but not required.  Just like
+#                                            expr-cont, above, except that no '/'
+#                                            look-ahead symbol is permitted.
+#
+expr-cont-no-slash:
+    escaped                 term                                    doExprCatOperator
+    white_space          n  expr-cont
+    rule_char               term                                    doExprCatOperator
+    '['                     term                                    doExprCatOperator
+    '('                     term                                    doExprCatOperator
+    '$'                     term                                    doExprCatOperator
+    '.'                     term                                    doExprCatOperator
+    '|'                  n  term                                    doExprOrOperator
+    ')'                  n  pop                                     doExprRParen
+    default                 pop                                     doExprFinished
+
+
+#
+#   tags             scanning a '{', the opening delimiter for a tag that identifies
+#                    the kind of match.  Scan the whole {dddd} tag, where d=digit
+#
+tag-open:
+    white_space          n  tag-open
+    digit_char              tag-value                               doStartTagValue
+    default                 errorDeath                              doTagExpectedError
+    
+tag-value:
+    white_space          n  tag-close
+    '}'                     tag-close
+    digit_char           n  tag-value                               doTagDigit
+    default                 errorDeath                              doTagExpectedError
+    
+tag-close:
+    white_space          n  tag-close
+    '}'                  n  expr-cont-no-tag                        doTagValue
+    default                 errorDeath                              doTagExpectedError
+    
+    
+    
+#
+#  expr-cont-no-tag    Expression, continuation.  At a point where additional terms are
+#                                            allowed, but not required.  Just like
+#                                            expr-cont, above, except that no "{ddd}"
+#                                            tagging is permitted.
+#
+expr-cont-no-tag:
+    escaped                 term                                    doExprCatOperator
+    white_space          n  expr-cont-no-tag
+    rule_char               term                                    doExprCatOperator
+    '['                     term                                    doExprCatOperator
+    '('                     term                                    doExprCatOperator
+    '$'                     term                                    doExprCatOperator
+    '.'                     term                                    doExprCatOperator
+    '/'                     look-ahead                              doExprCatOperator
+    '|'                  n  term                                    doExprOrOperator
+    ')'                  n  pop                                     doExprRParen
+    default                 pop                                     doExprFinished
+    
+    
+
+
+#
+#   Variable Name Scanning.
+#
+#                    The state that branched to here must have pushed a return state
+#                    to go to after completion of the variable name scanning.
+#
+#                    The current input character must be the $ that introduces the name.
+#                    The $ is consummed here rather than in the state that first detected it
+#                    so that the doStartVariableName action only needs to happen in one
+#                    place (here), and the other states don't need to worry about it.
+#
+scan-var-name:
+   '$'                  n scan-var-start                            doStartVariableName
+   default                errorDeath
+
+
+scan-var-start:
+    name_start_char      n scan-var-body
+    default                errorDeath                               doVariableNameExpectedErr
+    
+scan-var-body:
+    name_char            n scan-var-body
+    default                pop                                      doEndVariableName
+    
+    
+    
+#
+#  scan-unicode-set   Unicode Sets are parsed by the the UnicodeSet class.
+#                     Within the RBBI parser, after finding the first character
+#                     of a Unicode Set, we just hand the rule input at that
+#                     point of to the Unicode Set constructor, then pick
+#                     up parsing after the close of the set.
+#
+#                     The action for this state invokes the UnicodeSet parser.
+#
+scan-unicode-set:
+    '['                   n pop                                      doScanUnicodeSet
+    'p'                   n pop                                      doScanUnicodeSet
+    'P'                   n pop                                      doScanUnicodeSet
+    default		    errorDeath 
+    
+    
+
+
+
+
+
+#
+#  assign-or-rule.   A $variable was encountered at the start of something, could be
+#                    either an assignment statement or a rule, depending on whether an '='
+#                    follows the variable name.  We get to this state when the variable name
+#                    scanning does a return.
+#
+assign-or-rule:
+    white_space          n assign-or-rule
+    '='                  n term                  ^assign-end        doStartAssign   # variable was target of assignment
+    default                term-var-ref          ^break-rule-end                    # variable was a term in a rule
+
+
+
+#
+#  assign-end        This state is entered when the end of the expression on the
+#                    right hand side of an assignment is found.  We get here via
+#                    a pop; this state is pushed when the '=' in an assignment is found.
+#
+#                    The only thing allowed at this point is a ';'.  The RHS of an
+#                    assignment must look like a rule expression, and we come here
+#                    when what is being scanned no longer looks like an expression.
+#
+assign-end:
+    ';'                  n start                                    doEndAssign
+    default                errorDeath                               doRuleErrorAssignExpr
+    
+    
+    
+#
+# errorDeath.   This state is specified as the next state whenever a syntax error
+#               in the source rules is detected.  Barring bugs, the state machine will never
+#               actually get here, but will stop because of the action associated with the error.
+#               But, just in case, this state asks the state machine to exit.
+errorDeath:
+    default              n errorDeath                               doExit
+
+
diff --git a/icu/source/common/rbbiscan.cpp b/icu/source/common/rbbiscan.cpp
new file mode 100644
index 0000000..82147cd
--- /dev/null
+++ b/icu/source/common/rbbiscan.cpp
@@ -0,0 +1,1210 @@
+
+//
+//  file:  rbbiscan.cpp
+//
+//  Copyright (C) 2002-2008, International Business Machines Corporation and others.
+//  All Rights Reserved.
+//
+//  This file contains the Rule Based Break Iterator Rule Builder functions for
+//   scanning the rules and assembling a parse tree.  This is the first phase
+//   of compiling the rules.
+//
+//  The overall of the rules is managed by class RBBIRuleBuilder, which will
+//  create and use an instance of this class as part of the process.
+//
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/unistr.h"
+#include "unicode/uniset.h"
+#include "unicode/uchar.h"
+#include "unicode/uchriter.h"
+#include "unicode/parsepos.h"
+#include "unicode/parseerr.h"
+#include "util.h"
+#include "cmemory.h"
+#include "cstring.h"
+
+#include "rbbirpt.h"   // Contains state table for the rbbi rules parser.
+                       //   generated by a Perl script.
+#include "rbbirb.h"
+#include "rbbinode.h"
+#include "rbbiscan.h"
+#include "rbbitblb.h"
+
+#include "uassert.h"
+
+
+//------------------------------------------------------------------------------
+//
+// Unicode Set init strings for each of the character classes needed for parsing a rule file.
+//               (Initialized with hex values for portability to EBCDIC based machines.
+//                Really ugly, but there's no good way to avoid it.)
+//
+//              The sets are referred to by name in the rbbirpt.txt, which is the
+//              source form of the state transition table for the RBBI rule parser.
+//
+//------------------------------------------------------------------------------
+static const UChar gRuleSet_rule_char_pattern[]       = {
+ //   [    ^      [    \     p     {      Z     }     \     u    0      0    2      0
+    0x5b, 0x5e, 0x5b, 0x5c, 0x70, 0x7b, 0x5a, 0x7d, 0x5c, 0x75, 0x30, 0x30, 0x32, 0x30,
+ //   -    \      u    0     0     7      f     ]     -     [    \      p
+    0x2d, 0x5c, 0x75, 0x30, 0x30, 0x37, 0x66, 0x5d, 0x2d, 0x5b, 0x5c, 0x70,
+ //   {     L     }    ]     -     [      \     p     {     N    }      ]     ]
+    0x7b, 0x4c, 0x7d, 0x5d, 0x2d, 0x5b, 0x5c, 0x70, 0x7b, 0x4e, 0x7d, 0x5d, 0x5d, 0};
+
+static const UChar gRuleSet_name_char_pattern[]       = {
+//    [    _      \    p     {     L      }     \     p     {    N      }     ]
+    0x5b, 0x5f, 0x5c, 0x70, 0x7b, 0x4c, 0x7d, 0x5c, 0x70, 0x7b, 0x4e, 0x7d, 0x5d, 0};
+
+static const UChar gRuleSet_digit_char_pattern[] = {
+//    [    0      -    9     ]
+    0x5b, 0x30, 0x2d, 0x39, 0x5d, 0};
+
+static const UChar gRuleSet_name_start_char_pattern[] = {
+//    [    _      \    p     {     L      }     ]
+    0x5b, 0x5f, 0x5c, 0x70, 0x7b, 0x4c, 0x7d, 0x5d, 0 };
+
+static const UChar kAny[] = {0x61, 0x6e, 0x79, 0x00};  // "any"
+
+
+U_CDECL_BEGIN
+static void U_CALLCONV RBBISetTable_deleter(void *p) {
+    U_NAMESPACE_QUALIFIER RBBISetTableEl *px = (U_NAMESPACE_QUALIFIER RBBISetTableEl *)p;
+    delete px->key;
+    // Note:  px->val is owned by the linked list "fSetsListHead" in scanner.
+    //        Don't delete the value nodes here.
+    uprv_free(px);
+}
+U_CDECL_END
+
+U_NAMESPACE_BEGIN
+
+//------------------------------------------------------------------------------
+//
+//  Constructor.
+//
+//------------------------------------------------------------------------------
+RBBIRuleScanner::RBBIRuleScanner(RBBIRuleBuilder *rb)
+{
+    fRB                 = rb;
+    fStackPtr           = 0;
+    fStack[fStackPtr]   = 0;
+    fNodeStackPtr       = 0;
+    fRuleNum            = 0;
+    fNodeStack[0]       = NULL;
+
+    fSymbolTable                            = NULL;
+    fSetTable                               = NULL;
+
+    fScanIndex = 0;
+    fNextIndex = 0;
+
+    fReverseRule        = FALSE;
+    fLookAheadRule      = FALSE;
+
+    fLineNum    = 1;
+    fCharNum    = 0;
+    fQuoteMode  = FALSE;
+
+    // Do not check status until after all critical fields are sufficiently initialized
+    //   that the destructor can run cleanly.
+    if (U_FAILURE(*rb->fStatus)) {
+        return;
+    }
+
+    //
+    //  Set up the constant Unicode Sets.
+    //     Note:  These could be made static, lazily initialized, and shared among
+    //            all instances of RBBIRuleScanners.  BUT this is quite a bit simpler,
+    //            and the time to build these few sets should be small compared to a
+    //            full break iterator build.
+    fRuleSets[kRuleSet_rule_char-128]       = UnicodeSet(gRuleSet_rule_char_pattern,       *rb->fStatus);
+    UnicodeSet *whitespaceSet = uprv_openRuleWhiteSpaceSet(rb->fStatus);
+    if (U_FAILURE(*rb->fStatus)) {
+        return;
+    }
+    fRuleSets[kRuleSet_white_space-128]     = *whitespaceSet;
+    delete whitespaceSet;
+    fRuleSets[kRuleSet_name_char-128]       = UnicodeSet(gRuleSet_name_char_pattern,       *rb->fStatus);
+    fRuleSets[kRuleSet_name_start_char-128] = UnicodeSet(gRuleSet_name_start_char_pattern, *rb->fStatus);
+    fRuleSets[kRuleSet_digit_char-128]      = UnicodeSet(gRuleSet_digit_char_pattern,      *rb->fStatus);
+    if (*rb->fStatus == U_ILLEGAL_ARGUMENT_ERROR) {
+        // This case happens if ICU's data is missing.  UnicodeSet tries to look up property
+        //   names from the init string, can't find them, and claims an illegal arguement.
+        //   Change the error so that the actual problem will be clearer to users.
+        *rb->fStatus = U_BRK_INIT_ERROR;
+    }
+    if (U_FAILURE(*rb->fStatus)) {
+        return;
+    }
+
+    fSymbolTable = new RBBISymbolTable(this, rb->fRules, *rb->fStatus);
+    if (fSymbolTable == NULL) {
+        *rb->fStatus = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    fSetTable    = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, rb->fStatus);
+    if (U_FAILURE(*rb->fStatus)) {
+        return;
+    }
+    uhash_setValueDeleter(fSetTable, RBBISetTable_deleter);
+}
+
+
+
+//------------------------------------------------------------------------------
+//
+//  Destructor
+//
+//------------------------------------------------------------------------------
+RBBIRuleScanner::~RBBIRuleScanner() {
+    delete fSymbolTable;
+    if (fSetTable != NULL) {
+         uhash_close(fSetTable);
+         fSetTable = NULL;
+
+    }
+
+
+    // Node Stack.
+    //   Normally has one entry, which is the entire parse tree for the rules.
+    //   If errors occured, there may be additional subtrees left on the stack.
+    while (fNodeStackPtr > 0) {
+        delete fNodeStack[fNodeStackPtr];
+        fNodeStackPtr--;
+    }
+
+}
+
+//------------------------------------------------------------------------------
+//
+//  doParseAction        Do some action during rule parsing.
+//                       Called by the parse state machine.
+//                       Actions build the parse tree and Unicode Sets,
+//                       and maintain the parse stack for nested expressions.
+//
+//                       TODO:  unify EParseAction and RBBI_RuleParseAction enum types.
+//                              They represent exactly the same thing.  They're separate
+//                              only to work around enum forward declaration restrictions
+//                              in some compilers, while at the same time avoiding multiple
+//                              definitions problems.  I'm sure that there's a better way.
+//
+//------------------------------------------------------------------------------
+UBool RBBIRuleScanner::doParseActions(int32_t action)
+{
+    RBBINode *n       = NULL;
+
+    UBool   returnVal = TRUE;
+
+    switch (action) {
+
+    case doExprStart:
+        pushNewNode(RBBINode::opStart);
+        fRuleNum++;
+        break;
+
+
+    case doExprOrOperator:
+        {
+            fixOpStack(RBBINode::precOpCat);
+            RBBINode  *operandNode = fNodeStack[fNodeStackPtr--];
+            RBBINode  *orNode      = pushNewNode(RBBINode::opOr);
+            orNode->fLeftChild     = operandNode;
+            operandNode->fParent   = orNode;
+        }
+        break;
+
+    case doExprCatOperator:
+        // concatenation operator.
+        // For the implicit concatenation of adjacent terms in an expression that are
+        //   not separated by any other operator.  Action is invoked between the
+        //   actions for the two terms.
+        {
+            fixOpStack(RBBINode::precOpCat);
+            RBBINode  *operandNode = fNodeStack[fNodeStackPtr--];
+            RBBINode  *catNode     = pushNewNode(RBBINode::opCat);
+            catNode->fLeftChild    = operandNode;
+            operandNode->fParent   = catNode;
+        }
+        break;
+
+    case doLParen:
+        // Open Paren.
+        //   The openParen node is a dummy operation type with a low precedence,
+        //     which has the affect of ensuring that any real binary op that
+        //     follows within the parens binds more tightly to the operands than
+        //     stuff outside of the parens.
+        pushNewNode(RBBINode::opLParen);
+        break;
+
+    case doExprRParen:
+        fixOpStack(RBBINode::precLParen);
+        break;
+
+    case doNOP:
+        break;
+
+    case doStartAssign:
+        // We've just scanned "$variable = "
+        // The top of the node stack has the $variable ref node.
+
+        // Save the start position of the RHS text in the StartExpression node
+        //   that precedes the $variableReference node on the stack.
+        //   This will eventually be used when saving the full $variable replacement
+        //   text as a string.
+        n = fNodeStack[fNodeStackPtr-1];
+        n->fFirstPos = fNextIndex;              // move past the '='
+
+        // Push a new start-of-expression node; needed to keep parse of the
+        //   RHS expression happy.
+        pushNewNode(RBBINode::opStart);
+        break;
+
+
+
+
+    case doEndAssign:
+        {
+            // We have reached the end of an assignement statement.
+            //   Current scan char is the ';' that terminates the assignment.
+
+            // Terminate expression, leaves expression parse tree rooted in TOS node.
+            fixOpStack(RBBINode::precStart);
+
+            RBBINode *startExprNode  = fNodeStack[fNodeStackPtr-2];
+            RBBINode *varRefNode     = fNodeStack[fNodeStackPtr-1];
+            RBBINode *RHSExprNode    = fNodeStack[fNodeStackPtr];
+
+            // Save original text of right side of assignment, excluding the terminating ';'
+            //  in the root of the node for the right-hand-side expression.
+            RHSExprNode->fFirstPos = startExprNode->fFirstPos;
+            RHSExprNode->fLastPos  = fScanIndex;
+            fRB->fRules.extractBetween(RHSExprNode->fFirstPos, RHSExprNode->fLastPos, RHSExprNode->fText);
+
+            // Expression parse tree becomes l. child of the $variable reference node.
+            varRefNode->fLeftChild = RHSExprNode;
+            RHSExprNode->fParent   = varRefNode;
+
+            // Make a symbol table entry for the $variableRef node.
+            fSymbolTable->addEntry(varRefNode->fText, varRefNode, *fRB->fStatus);
+            if (U_FAILURE(*fRB->fStatus)) {
+                // This is a round-about way to get the parse position set
+                //  so that duplicate symbols error messages include a line number.
+                UErrorCode t = *fRB->fStatus;
+                *fRB->fStatus = U_ZERO_ERROR;
+                error(t);
+            }
+
+            // Clean up the stack.
+            delete startExprNode;
+            fNodeStackPtr-=3;
+            break;
+        }
+
+    case doEndOfRule:
+        {
+        fixOpStack(RBBINode::precStart);      // Terminate expression, leaves expression
+        if (U_FAILURE(*fRB->fStatus)) {       //   parse tree rooted in TOS node.
+            break;
+        }
+#ifdef RBBI_DEBUG
+        if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "rtree")) {printNodeStack("end of rule");}
+#endif
+        U_ASSERT(fNodeStackPtr == 1);
+
+        // If this rule includes a look-ahead '/', add a endMark node to the
+        //   expression tree.
+        if (fLookAheadRule) {
+            RBBINode  *thisRule       = fNodeStack[fNodeStackPtr];
+            RBBINode  *endNode        = pushNewNode(RBBINode::endMark);
+            RBBINode  *catNode        = pushNewNode(RBBINode::opCat);
+            fNodeStackPtr -= 2;
+            catNode->fLeftChild       = thisRule;
+            catNode->fRightChild      = endNode;
+            fNodeStack[fNodeStackPtr] = catNode;
+            endNode->fVal             = fRuleNum;
+            endNode->fLookAheadEnd    = TRUE;
+        }
+
+        // All rule expressions are ORed together.
+        // The ';' that terminates an expression really just functions as a '|' with
+        //   a low operator prededence.
+        //
+        // Each of the four sets of rules are collected separately.
+        //  (forward, reverse, safe_forward, safe_reverse)
+        //  OR this rule into the appropriate group of them.
+        //
+        RBBINode **destRules = (fReverseRule? &fRB->fReverseTree : fRB->fDefaultTree);
+
+        if (*destRules != NULL) {
+            // This is not the first rule encounted.
+            // OR previous stuff  (from *destRules)
+            // with the current rule expression (on the Node Stack)
+            //  with the resulting OR expression going to *destRules
+            //
+            RBBINode  *thisRule    = fNodeStack[fNodeStackPtr];
+            RBBINode  *prevRules   = *destRules;
+            RBBINode  *orNode      = pushNewNode(RBBINode::opOr);
+            orNode->fLeftChild     = prevRules;
+            prevRules->fParent     = orNode;
+            orNode->fRightChild    = thisRule;
+            thisRule->fParent      = orNode;
+            *destRules             = orNode;
+        }
+        else
+        {
+            // This is the first rule encountered (for this direction).
+            // Just move its parse tree from the stack to *destRules.
+            *destRules = fNodeStack[fNodeStackPtr];
+        }
+        fReverseRule   = FALSE;   // in preparation for the next rule.
+        fLookAheadRule = FALSE;
+        fNodeStackPtr  = 0;
+        }
+        break;
+
+
+    case doRuleError:
+        error(U_BRK_RULE_SYNTAX);
+        returnVal = FALSE;
+        break;
+
+
+    case doVariableNameExpectedErr:
+        error(U_BRK_RULE_SYNTAX);
+        break;
+
+
+    //
+    //  Unary operands  + ? *
+    //    These all appear after the operand to which they apply.
+    //    When we hit one, the operand (may be a whole sub expression)
+    //    will be on the top of the stack.
+    //    Unary Operator becomes TOS, with the old TOS as its one child.
+    case doUnaryOpPlus:
+        {
+            RBBINode  *operandNode = fNodeStack[fNodeStackPtr--];
+            RBBINode  *plusNode    = pushNewNode(RBBINode::opPlus);
+            plusNode->fLeftChild   = operandNode;
+            operandNode->fParent   = plusNode;
+        }
+        break;
+
+    case doUnaryOpQuestion:
+        {
+            RBBINode  *operandNode = fNodeStack[fNodeStackPtr--];
+            RBBINode  *qNode       = pushNewNode(RBBINode::opQuestion);
+            qNode->fLeftChild      = operandNode;
+            operandNode->fParent   = qNode;
+        }
+        break;
+
+    case doUnaryOpStar:
+        {
+            RBBINode  *operandNode = fNodeStack[fNodeStackPtr--];
+            RBBINode  *starNode    = pushNewNode(RBBINode::opStar);
+            starNode->fLeftChild   = operandNode;
+            operandNode->fParent   = starNode;
+        }
+        break;
+
+    case doRuleChar:
+        // A "Rule Character" is any single character that is a literal part
+        // of the regular expression.  Like a, b and c in the expression "(abc*) | [:L:]"
+        // These are pretty uncommon in break rules; the terms are more commonly
+        //  sets.  To keep things uniform, treat these characters like as
+        // sets that just happen to contain only one character.
+        {
+            n = pushNewNode(RBBINode::setRef);
+            findSetFor(fC.fChar, n);
+            n->fFirstPos = fScanIndex;
+            n->fLastPos  = fNextIndex;
+            fRB->fRules.extractBetween(n->fFirstPos, n->fLastPos, n->fText);
+            break;
+        }
+
+    case doDotAny:
+        // scanned a ".", meaning match any single character.
+        {
+            n = pushNewNode(RBBINode::setRef);
+            findSetFor(kAny, n);
+            n->fFirstPos = fScanIndex;
+            n->fLastPos  = fNextIndex;
+            fRB->fRules.extractBetween(n->fFirstPos, n->fLastPos, n->fText);
+            break;
+        }
+
+    case doSlash:
+        // Scanned a '/', which identifies a look-ahead break position in a rule.
+        n = pushNewNode(RBBINode::lookAhead);
+        n->fVal      = fRuleNum;
+        n->fFirstPos = fScanIndex;
+        n->fLastPos  = fNextIndex;
+        fRB->fRules.extractBetween(n->fFirstPos, n->fLastPos, n->fText);
+        fLookAheadRule = TRUE;
+        break;
+
+
+    case doStartTagValue:
+        // Scanned a '{', the opening delimiter for a tag value within a rule.
+        n = pushNewNode(RBBINode::tag);
+        n->fVal      = 0;
+        n->fFirstPos = fScanIndex;
+        n->fLastPos  = fNextIndex;
+        break;
+
+    case doTagDigit:
+        // Just scanned a decimal digit that's part of a tag value
+        {
+            n = fNodeStack[fNodeStackPtr];
+            uint32_t v = u_charDigitValue(fC.fChar);
+            U_ASSERT(v < 10);
+            n->fVal = n->fVal*10 + v;
+            break;
+        }
+
+    case doTagValue:
+        n = fNodeStack[fNodeStackPtr];
+        n->fLastPos = fNextIndex;
+        fRB->fRules.extractBetween(n->fFirstPos, n->fLastPos, n->fText);
+        break;
+
+    case doTagExpectedError:
+        error(U_BRK_MALFORMED_RULE_TAG);
+        returnVal = FALSE;
+        break;
+
+    case doOptionStart:
+        // Scanning a !!option.   At the start of string.
+        fOptionStart = fScanIndex;
+        break;
+
+    case doOptionEnd:
+        {
+            UnicodeString opt(fRB->fRules, fOptionStart, fScanIndex-fOptionStart);
+            if (opt == UNICODE_STRING("chain", 5)) {
+                fRB->fChainRules = TRUE;
+            } else if (opt == UNICODE_STRING("LBCMNoChain", 11)) {
+                fRB->fLBCMNoChain = TRUE;
+            } else if (opt == UNICODE_STRING("forward", 7)) {
+                fRB->fDefaultTree   = &fRB->fForwardTree;
+            } else if (opt == UNICODE_STRING("reverse", 7)) {
+                fRB->fDefaultTree   = &fRB->fReverseTree;
+            } else if (opt == UNICODE_STRING("safe_forward", 12)) {
+                fRB->fDefaultTree   = &fRB->fSafeFwdTree;
+            } else if (opt == UNICODE_STRING("safe_reverse", 12)) {
+                fRB->fDefaultTree   = &fRB->fSafeRevTree;
+            } else if (opt == UNICODE_STRING("lookAheadHardBreak", 18)) {
+                fRB->fLookAheadHardBreak = TRUE;
+            } else {
+                error(U_BRK_UNRECOGNIZED_OPTION);
+            }
+        }
+        break;
+
+    case doReverseDir:
+        fReverseRule = TRUE;
+        break;
+
+    case doStartVariableName:
+        n = pushNewNode(RBBINode::varRef);
+        if (U_FAILURE(*fRB->fStatus)) {
+            break;
+        }
+        n->fFirstPos = fScanIndex;
+        break;
+
+    case doEndVariableName:
+        n = fNodeStack[fNodeStackPtr];
+        if (n==NULL || n->fType != RBBINode::varRef) {
+            error(U_BRK_INTERNAL_ERROR);
+            break;
+        }
+        n->fLastPos = fScanIndex;
+        fRB->fRules.extractBetween(n->fFirstPos+1, n->fLastPos, n->fText);
+        // Look the newly scanned name up in the symbol table
+        //   If there's an entry, set the l. child of the var ref to the replacement expression.
+        //   (We also pass through here when scanning assignments, but no harm is done, other
+        //    than a slight wasted effort that seems hard to avoid.  Lookup will be null)
+        n->fLeftChild = fSymbolTable->lookupNode(n->fText);
+        break;
+
+    case doCheckVarDef:
+        n = fNodeStack[fNodeStackPtr];
+        if (n->fLeftChild == NULL) {
+            error(U_BRK_UNDEFINED_VARIABLE);
+            returnVal = FALSE;
+        }
+        break;
+
+    case doExprFinished:
+        break;
+
+    case doRuleErrorAssignExpr:
+        error(U_BRK_ASSIGN_ERROR);
+        returnVal = FALSE;
+        break;
+
+    case doExit:
+        returnVal = FALSE;
+        break;
+
+    case doScanUnicodeSet:
+        scanSet();
+        break;
+
+    default:
+        error(U_BRK_INTERNAL_ERROR);
+        returnVal = FALSE;
+        break;
+    }
+    return returnVal;
+}
+
+
+
+
+//------------------------------------------------------------------------------
+//
+//  Error         Report a rule parse error.
+//                Only report it if no previous error has been recorded.
+//
+//------------------------------------------------------------------------------
+void RBBIRuleScanner::error(UErrorCode e) {
+    if (U_SUCCESS(*fRB->fStatus)) {
+        *fRB->fStatus = e;
+        if (fRB->fParseError) {
+            fRB->fParseError->line  = fLineNum;
+            fRB->fParseError->offset = fCharNum;
+            fRB->fParseError->preContext[0] = 0;
+            fRB->fParseError->preContext[0] = 0;
+        }
+    }
+}
+
+
+
+
+//------------------------------------------------------------------------------
+//
+//  fixOpStack   The parse stack holds partially assembled chunks of the parse tree.
+//               An entry on the stack may be as small as a single setRef node,
+//               or as large as the parse tree
+//               for an entire expression (this will be the one item left on the stack
+//               when the parsing of an RBBI rule completes.
+//
+//               This function is called when a binary operator is encountered.
+//               It looks back up the stack for operators that are not yet associated
+//               with a right operand, and if the precedence of the stacked operator >=
+//               the precedence of the current operator, binds the operand left,
+//               to the previously encountered operator.
+//
+//------------------------------------------------------------------------------
+void RBBIRuleScanner::fixOpStack(RBBINode::OpPrecedence p) {
+    RBBINode *n;
+    // printNodeStack("entering fixOpStack()");
+    for (;;) {
+        n = fNodeStack[fNodeStackPtr-1];   // an operator node
+        if (n->fPrecedence == 0) {
+            RBBIDebugPuts("RBBIRuleScanner::fixOpStack, bad operator node");
+            error(U_BRK_INTERNAL_ERROR);
+            return;
+        }
+
+        if (n->fPrecedence < p || n->fPrecedence <= RBBINode::precLParen) {
+            // The most recent operand goes with the current operator,
+            //   not with the previously stacked one.
+            break;
+        }
+            // Stack operator is a binary op  ( '|' or concatenation)
+            //   TOS operand becomes right child of this operator.
+            //   Resulting subexpression becomes the TOS operand.
+            n->fRightChild = fNodeStack[fNodeStackPtr];
+            fNodeStack[fNodeStackPtr]->fParent = n;
+            fNodeStackPtr--;
+        // printNodeStack("looping in fixOpStack()   ");
+    }
+
+    if (p <= RBBINode::precLParen) {
+        // Scan is at a right paren or end of expression.
+        //  The scanned item must match the stack, or else there was an error.
+        //  Discard the left paren (or start expr) node from the stack,
+            //  leaving the completed (sub)expression as TOS.
+            if (n->fPrecedence != p) {
+                // Right paren encountered matched start of expression node, or
+                // end of expression matched with a left paren node.
+                error(U_BRK_MISMATCHED_PAREN);
+            }
+            fNodeStack[fNodeStackPtr-1] = fNodeStack[fNodeStackPtr];
+            fNodeStackPtr--;
+            // Delete the now-discarded LParen or Start node.
+            delete n;
+    }
+    // printNodeStack("leaving fixOpStack()");
+}
+
+
+
+
+//------------------------------------------------------------------------------
+//
+//   findSetFor    given a UnicodeString,
+//                  - find the corresponding Unicode Set  (uset node)
+//                         (create one if necessary)
+//                  - Set fLeftChild of the caller's node (should be a setRef node)
+//                         to the uset node
+//                 Maintain a hash table of uset nodes, so the same one is always used
+//                    for the same string.
+//                 If a "to adopt" set is provided and we haven't seen this key before,
+//                    add the provided set to the hash table.
+//                 If the string is one (32 bit) char in length, the set contains
+//                    just one element which is the char in question.
+//                 If the string is "any", return a set containing all chars.
+//
+//------------------------------------------------------------------------------
+void RBBIRuleScanner::findSetFor(const UnicodeString &s, RBBINode *node, UnicodeSet *setToAdopt) {
+
+    RBBISetTableEl   *el;
+
+    // First check whether we've already cached a set for this string.
+    // If so, just use the cached set in the new node.
+    //   delete any set provided by the caller, since we own it.
+    el = (RBBISetTableEl *)uhash_get(fSetTable, &s);
+    if (el != NULL) {
+        delete setToAdopt;
+        node->fLeftChild = el->val;
+        U_ASSERT(node->fLeftChild->fType == RBBINode::uset);
+        return;
+    }
+
+    // Haven't seen this set before.
+    // If the caller didn't provide us with a prebuilt set,
+    //   create a new UnicodeSet now.
+    if (setToAdopt == NULL) {
+        if (s.compare(kAny, -1) == 0) {
+            setToAdopt = new UnicodeSet(0x000000, 0x10ffff);
+        } else {
+            UChar32 c;
+            c = s.char32At(0);
+            setToAdopt = new UnicodeSet(c, c);
+        }
+    }
+
+    //
+    // Make a new uset node to refer to this UnicodeSet
+    // This new uset node becomes the child of the caller's setReference node.
+    //
+    RBBINode *usetNode    = new RBBINode(RBBINode::uset);
+    if (usetNode == NULL) {
+        error(U_MEMORY_ALLOCATION_ERROR);
+        return;
+    }
+    usetNode->fInputSet   = setToAdopt;
+    usetNode->fParent     = node;
+    node->fLeftChild      = usetNode;
+    usetNode->fText = s;
+
+
+    //
+    // Add the new uset node to the list of all uset nodes.
+    //
+    fRB->fUSetNodes->addElement(usetNode, *fRB->fStatus);
+
+
+    //
+    // Add the new set to the set hash table.
+    //
+    el      = (RBBISetTableEl *)uprv_malloc(sizeof(RBBISetTableEl));
+    UnicodeString *tkey = new UnicodeString(s);
+    if (tkey == NULL || el == NULL || setToAdopt == NULL) {
+        // Delete to avoid memory leak
+        delete tkey;
+        tkey = NULL;
+        uprv_free(el);
+        el = NULL;
+        delete setToAdopt;
+        setToAdopt = NULL;
+
+        error(U_MEMORY_ALLOCATION_ERROR);
+        return;
+    }
+    el->key = tkey;
+    el->val = usetNode;
+    uhash_put(fSetTable, el->key, el, fRB->fStatus);
+
+    return;
+}
+
+
+
+//
+//  Assorted Unicode character constants.
+//     Numeric because there is no portable way to enter them as literals.
+//     (Think EBCDIC).
+//
+static const UChar      chCR        = 0x0d;      // New lines, for terminating comments.
+static const UChar      chLF        = 0x0a;
+static const UChar      chNEL       = 0x85;      //    NEL newline variant
+static const UChar      chLS        = 0x2028;    //    Unicode Line Separator
+static const UChar      chApos      = 0x27;      //  single quote, for quoted chars.
+static const UChar      chPound     = 0x23;      // '#', introduces a comment.
+static const UChar      chBackSlash = 0x5c;      // '\'  introduces a char escape
+static const UChar      chLParen    = 0x28;
+static const UChar      chRParen    = 0x29;
+
+
+//------------------------------------------------------------------------------
+//
+//  stripRules    Return a rules string without unnecessary
+//                characters.
+//
+//------------------------------------------------------------------------------
+UnicodeString RBBIRuleScanner::stripRules(const UnicodeString &rules) {
+    UnicodeString strippedRules;
+    int rulesLength = rules.length();
+    for (int idx = 0; idx < rulesLength; ) {
+        UChar ch = rules[idx++];
+        if (ch == chPound) {
+            while (idx < rulesLength
+                && ch != chCR && ch != chLF && ch != chNEL)
+            {
+                ch = rules[idx++];
+            }
+        }
+        if (!u_isISOControl(ch)) {
+            strippedRules.append(ch);
+        }
+    }
+    // strippedRules = strippedRules.unescape();
+    return strippedRules;
+}
+
+
+//------------------------------------------------------------------------------
+//
+//  nextCharLL    Low Level Next Char from rule input source.
+//                Get a char from the input character iterator,
+//                keep track of input position for error reporting.
+//
+//------------------------------------------------------------------------------
+UChar32  RBBIRuleScanner::nextCharLL() {
+    UChar32  ch;
+
+    if (fNextIndex >= fRB->fRules.length()) {
+        return (UChar32)-1;
+    }
+    ch         = fRB->fRules.char32At(fNextIndex);
+    fNextIndex = fRB->fRules.moveIndex32(fNextIndex, 1);
+
+    if (ch == chCR ||
+        ch == chNEL ||
+        ch == chLS   ||
+        ch == chLF && fLastChar != chCR) {
+        // Character is starting a new line.  Bump up the line number, and
+        //  reset the column to 0.
+        fLineNum++;
+        fCharNum=0;
+        if (fQuoteMode) {
+            error(U_BRK_NEW_LINE_IN_QUOTED_STRING);
+            fQuoteMode = FALSE;
+        }
+    }
+    else {
+        // Character is not starting a new line.  Except in the case of a
+        //   LF following a CR, increment the column position.
+        if (ch != chLF) {
+            fCharNum++;
+        }
+    }
+    fLastChar = ch;
+    return ch;
+}
+
+
+//------------------------------------------------------------------------------
+//
+//   nextChar     for rules scanning.  At this level, we handle stripping
+//                out comments and processing backslash character escapes.
+//                The rest of the rules grammar is handled at the next level up.
+//
+//------------------------------------------------------------------------------
+void RBBIRuleScanner::nextChar(RBBIRuleChar &c) {
+
+    // Unicode Character constants needed for the processing done by nextChar(),
+    //   in hex because literals wont work on EBCDIC machines.
+
+    fScanIndex = fNextIndex;
+    c.fChar    = nextCharLL();
+    c.fEscaped = FALSE;
+
+    //
+    //  check for '' sequence.
+    //  These are recognized in all contexts, whether in quoted text or not.
+    //
+    if (c.fChar == chApos) {
+        if (fRB->fRules.char32At(fNextIndex) == chApos) {
+            c.fChar    = nextCharLL();        // get nextChar officially so character counts
+            c.fEscaped = TRUE;                //   stay correct.
+        }
+        else
+        {
+            // Single quote, by itself.
+            //   Toggle quoting mode.
+            //   Return either '('  or ')', because quotes cause a grouping of the quoted text.
+            fQuoteMode = !fQuoteMode;
+            if (fQuoteMode == TRUE) {
+                c.fChar = chLParen;
+            } else {
+                c.fChar = chRParen;
+            }
+            c.fEscaped = FALSE;      // The paren that we return is not escaped.
+            return;
+        }
+    }
+
+    if (fQuoteMode) {
+        c.fEscaped = TRUE;
+    }
+    else
+    {
+        // We are not in a 'quoted region' of the source.
+        //
+        if (c.fChar == chPound) {
+            // Start of a comment.  Consume the rest of it.
+            //  The new-line char that terminates the comment is always returned.
+            //  It will be treated as white-space, and serves to break up anything
+            //    that might otherwise incorrectly clump together with a comment in
+            //    the middle (a variable name, for example.)
+            for (;;) {
+                c.fChar = nextCharLL();
+                if (c.fChar == (UChar32)-1 ||  // EOF
+                    c.fChar == chCR     ||
+                    c.fChar == chLF     ||
+                    c.fChar == chNEL    ||
+                    c.fChar == chLS)       {break;}
+            }
+        }
+        if (c.fChar == (UChar32)-1) {
+            return;
+        }
+
+        //
+        //  check for backslash escaped characters.
+        //  Use UnicodeString::unescapeAt() to handle them.
+        //
+        if (c.fChar == chBackSlash) {
+            c.fEscaped = TRUE;
+            int32_t startX = fNextIndex;
+            c.fChar = fRB->fRules.unescapeAt(fNextIndex);
+            if (fNextIndex == startX) {
+                error(U_BRK_HEX_DIGITS_EXPECTED);
+            }
+            fCharNum += fNextIndex-startX;
+        }
+    }
+    // putc(c.fChar, stdout);
+}
+
+//------------------------------------------------------------------------------
+//
+//  Parse RBBI rules.   The state machine for rules parsing is here.
+//                      The state tables are hand-written in the file rbbirpt.txt,
+//                      and converted to the form used here by a perl
+//                      script rbbicst.pl
+//
+//------------------------------------------------------------------------------
+void RBBIRuleScanner::parse() {
+    uint16_t                state;
+    const RBBIRuleTableEl  *tableEl;
+
+    if (U_FAILURE(*fRB->fStatus)) {
+        return;
+    }
+
+    state = 1;
+    nextChar(fC);
+    //
+    // Main loop for the rule parsing state machine.
+    //   Runs once per state transition.
+    //   Each time through optionally performs, depending on the state table,
+    //      - an advance to the the next input char
+    //      - an action to be performed.
+    //      - pushing or popping a state to/from the local state return stack.
+    //
+    for (;;) {
+        //  Bail out if anything has gone wrong.
+        //  RBBI rule file parsing stops on the first error encountered.
+        if (U_FAILURE(*fRB->fStatus)) {
+            break;
+        }
+
+        // Quit if state == 0.  This is the normal way to exit the state machine.
+        //
+        if (state == 0) {
+            break;
+        }
+
+        // Find the state table element that matches the input char from the rule, or the
+        //    class of the input character.  Start with the first table row for this
+        //    state, then linearly scan forward until we find a row that matches the
+        //    character.  The last row for each state always matches all characters, so
+        //    the search will stop there, if not before.
+        //
+        tableEl = &gRuleParseStateTable[state];
+        #ifdef RBBI_DEBUG
+            if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "scan")) {
+                RBBIDebugPrintf("char, line, col = (\'%c\', %d, %d)    state=%s ",
+                    fC.fChar, fLineNum, fCharNum, RBBIRuleStateNames[state]);
+            }
+        #endif
+
+        for (;;) {
+            #ifdef RBBI_DEBUG
+                if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "scan")) { RBBIDebugPrintf(".");}
+            #endif
+            if (tableEl->fCharClass < 127 && fC.fEscaped == FALSE &&   tableEl->fCharClass == fC.fChar) {
+                // Table row specified an individual character, not a set, and
+                //   the input character is not escaped, and
+                //   the input character matched it.
+                break;
+            }
+            if (tableEl->fCharClass == 255) {
+                // Table row specified default, match anything character class.
+                break;
+            }
+            if (tableEl->fCharClass == 254 && fC.fEscaped)  {
+                // Table row specified "escaped" and the char was escaped.
+                break;
+            }
+            if (tableEl->fCharClass == 253 && fC.fEscaped &&
+                (fC.fChar == 0x50 || fC.fChar == 0x70 ))  {
+                // Table row specified "escaped P" and the char is either 'p' or 'P'.
+                break;
+            }
+            if (tableEl->fCharClass == 252 && fC.fChar == (UChar32)-1)  {
+                // Table row specified eof and we hit eof on the input.
+                break;
+            }
+
+            if (tableEl->fCharClass >= 128 && tableEl->fCharClass < 240 &&   // Table specs a char class &&
+                fC.fEscaped == FALSE &&                                      //   char is not escaped &&
+                fC.fChar != (UChar32)-1) {                                   //   char is not EOF
+                if (fRuleSets[tableEl->fCharClass-128].contains(fC.fChar)) {
+                    // Table row specified a character class, or set of characters,
+                    //   and the current char matches it.
+                    break;
+                }
+            }
+
+            // No match on this row, advance to the next  row for this state,
+            tableEl++;
+        }
+        if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "scan")) { RBBIDebugPuts("");}
+
+        //
+        // We've found the row of the state table that matches the current input
+        //   character from the rules string.
+        // Perform any action specified  by this row in the state table.
+        if (doParseActions((int32_t)tableEl->fAction) == FALSE) {
+            // Break out of the state machine loop if the
+            //   the action signalled some kind of error, or
+            //   the action was to exit, occurs on normal end-of-rules-input.
+            break;
+        }
+
+        if (tableEl->fPushState != 0) {
+            fStackPtr++;
+            if (fStackPtr >= kStackSize) {
+                error(U_BRK_INTERNAL_ERROR);
+                RBBIDebugPuts("RBBIRuleScanner::parse() - state stack overflow.");
+                fStackPtr--;
+            }
+            fStack[fStackPtr] = tableEl->fPushState;
+        }
+
+        if (tableEl->fNextChar) {
+            nextChar(fC);
+        }
+
+        // Get the next state from the table entry, or from the
+        //   state stack if the next state was specified as "pop".
+        if (tableEl->fNextState != 255) {
+            state = tableEl->fNextState;
+        } else {
+            state = fStack[fStackPtr];
+            fStackPtr--;
+            if (fStackPtr < 0) {
+                error(U_BRK_INTERNAL_ERROR);
+                RBBIDebugPuts("RBBIRuleScanner::parse() - state stack underflow.");
+                fStackPtr++;
+            }
+        }
+
+    }
+
+    //
+    // If there were NO user specified reverse rules, set up the equivalent of ".*;"
+    //
+    if (fRB->fReverseTree == NULL) {
+        fRB->fReverseTree  = pushNewNode(RBBINode::opStar);
+        RBBINode  *operand = pushNewNode(RBBINode::setRef);
+        findSetFor(kAny, operand);
+        fRB->fReverseTree->fLeftChild = operand;
+        operand->fParent              = fRB->fReverseTree;
+        fNodeStackPtr -= 2;
+    }
+
+
+    //
+    // Parsing of the input RBBI rules is complete.
+    // We now have a parse tree for the rule expressions
+    // and a list of all UnicodeSets that are referenced.
+    //
+#ifdef RBBI_DEBUG
+    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "symbols")) {fSymbolTable->rbbiSymtablePrint();}
+    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "ptree"))
+    {
+        RBBIDebugPrintf("Completed Forward Rules Parse Tree...\n");
+        fRB->fForwardTree->printTree(TRUE);
+        RBBIDebugPrintf("\nCompleted Reverse Rules Parse Tree...\n");
+        fRB->fReverseTree->printTree(TRUE);
+        RBBIDebugPrintf("\nCompleted Safe Point Forward Rules Parse Tree...\n");
+        fRB->fSafeFwdTree->printTree(TRUE);
+        RBBIDebugPrintf("\nCompleted Safe Point Reverse Rules Parse Tree...\n");
+        fRB->fSafeRevTree->printTree(TRUE);
+    }
+#endif
+}
+
+
+//------------------------------------------------------------------------------
+//
+//  printNodeStack     for debugging...
+//
+//------------------------------------------------------------------------------
+#ifdef RBBI_DEBUG
+void RBBIRuleScanner::printNodeStack(const char *title) {
+    int i;
+    RBBIDebugPrintf("%s.  Dumping node stack...\n", title);
+    for (i=fNodeStackPtr; i>0; i--) {fNodeStack[i]->printTree(TRUE);}
+}
+#endif
+
+
+
+
+//------------------------------------------------------------------------------
+//
+//  pushNewNode   create a new RBBINode of the specified type and push it
+//                onto the stack of nodes.
+//
+//------------------------------------------------------------------------------
+RBBINode  *RBBIRuleScanner::pushNewNode(RBBINode::NodeType  t) {
+    fNodeStackPtr++;
+    if (fNodeStackPtr >= kStackSize) {
+        error(U_BRK_INTERNAL_ERROR);
+        RBBIDebugPuts("RBBIRuleScanner::pushNewNode - stack overflow.");
+        *fRB->fStatus = U_BRK_INTERNAL_ERROR;
+        return NULL;
+    }
+    fNodeStack[fNodeStackPtr] = new RBBINode(t);
+    if (fNodeStack[fNodeStackPtr] == NULL) {
+        *fRB->fStatus = U_MEMORY_ALLOCATION_ERROR;
+    }
+    return fNodeStack[fNodeStackPtr];
+}
+
+
+
+//------------------------------------------------------------------------------
+//
+//  scanSet    Construct a UnicodeSet from the text at the current scan
+//             position.  Advance the scan position to the first character
+//             after the set.
+//
+//             A new RBBI setref node referring to the set is pushed onto the node
+//             stack.
+//
+//             The scan position is normally under the control of the state machine
+//             that controls rule parsing.  UnicodeSets, however, are parsed by
+//             the UnicodeSet constructor, not by the RBBI rule parser.
+//
+//------------------------------------------------------------------------------
+void RBBIRuleScanner::scanSet() {
+    UnicodeSet    *uset;
+    ParsePosition  pos;
+    int            startPos;
+    int            i;
+
+    if (U_FAILURE(*fRB->fStatus)) {
+        return;
+    }
+
+    pos.setIndex(fScanIndex);
+    startPos = fScanIndex;
+    UErrorCode localStatus = U_ZERO_ERROR;
+    uset = new UnicodeSet(fRB->fRules, pos, USET_IGNORE_SPACE,
+                         fSymbolTable,
+                         localStatus);
+    if (uset == NULL) {
+        localStatus = U_MEMORY_ALLOCATION_ERROR;
+    }
+    if (U_FAILURE(localStatus)) {
+        //  TODO:  Get more accurate position of the error from UnicodeSet's return info.
+        //         UnicodeSet appears to not be reporting correctly at this time.
+        #ifdef RBBI_DEBUG
+            RBBIDebugPrintf("UnicodeSet parse postion.ErrorIndex = %d\n", pos.getIndex());
+        #endif
+        error(localStatus);
+        delete uset;
+        return;
+    }
+
+    // Verify that the set contains at least one code point.
+    //
+    if (uset->isEmpty()) {
+        // This set is empty.
+        //  Make it an error, because it almost certainly is not what the user wanted.
+        //  Also, avoids having to think about corner cases in the tree manipulation code
+        //   that occurs later on.
+        error(U_BRK_RULE_EMPTY_SET);
+        delete uset;
+        return;
+    }
+
+
+    // Advance the RBBI parse postion over the UnicodeSet pattern.
+    //   Don't just set fScanIndex because the line/char positions maintained
+    //   for error reporting would be thrown off.
+    i = pos.getIndex();
+    for (;;) {
+        if (fNextIndex >= i) {
+            break;
+        }
+        nextCharLL();
+    }
+
+    if (U_SUCCESS(*fRB->fStatus)) {
+        RBBINode         *n;
+
+        n = pushNewNode(RBBINode::setRef);
+        n->fFirstPos = startPos;
+        n->fLastPos  = fNextIndex;
+        fRB->fRules.extractBetween(n->fFirstPos, n->fLastPos, n->fText);
+        //  findSetFor() serves several purposes here:
+        //     - Adopts storage for the UnicodeSet, will be responsible for deleting.
+        //     - Mantains collection of all sets in use, needed later for establishing
+        //          character categories for run time engine.
+        //     - Eliminates mulitiple instances of the same set.
+        //     - Creates a new uset node if necessary (if this isn't a duplicate.)
+        findSetFor(n->fText, n, uset);
+    }
+
+}
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/icu/source/common/rbbiscan.h b/icu/source/common/rbbiscan.h
new file mode 100644
index 0000000..dd9b8e6
--- /dev/null
+++ b/icu/source/common/rbbiscan.h
@@ -0,0 +1,162 @@
+//
+//  rbbiscan.h
+//
+//  Copyright (C) 2002-2008, International Business Machines Corporation and others.
+//  All Rights Reserved.
+//
+//  This file contains declarations for class RBBIRuleScanner
+//
+
+
+#ifndef RBBISCAN_H
+#define RBBISCAN_H
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+#include "unicode/rbbi.h"
+#include "unicode/uniset.h"
+#include "unicode/parseerr.h"
+#include "uhash.h"
+#include "uvector.h"
+#include "unicode/symtable.h"// For UnicodeSet parsing, is the interface that
+                          //    looks up references to $variables within a set.
+#include "rbbinode.h"
+//#include "rbbitblb.h"
+
+
+
+U_NAMESPACE_BEGIN
+
+class   RBBIRuleBuilder;
+class   RBBISymbolTable;
+
+
+//--------------------------------------------------------------------------------
+//
+//  class RBBIRuleScanner does the lowest level, character-at-a-time
+//                        scanning of break iterator rules.  
+//
+//                        The output of the scanner is parse trees for
+//                        the rule expressions and a list of all Unicode Sets
+//                        encountered.
+//
+//--------------------------------------------------------------------------------
+
+class RBBIRuleScanner : public UMemory {
+public:
+
+    enum {
+        kStackSize = 100            // The size of the state stack for
+    };                              //   rules parsing.  Corresponds roughly
+                                    //   to the depth of parentheses nesting
+                                    //   that is allowed in the rules.
+
+    struct RBBIRuleChar {
+        UChar32             fChar;
+        UBool               fEscaped;
+    };
+
+    RBBIRuleScanner(RBBIRuleBuilder  *rb);
+
+
+    virtual    ~RBBIRuleScanner();
+
+    void        nextChar(RBBIRuleChar &c);          // Get the next char from the input stream.
+                                                    // Return false if at end.
+
+    UBool       push(const RBBIRuleChar &c);        // Push (unget) one character.
+                                                    //   Only a single character may be pushed.
+
+    void        parse();                            // Parse the rules, generating two parse
+                                                    //   trees, one each for the forward and
+                                                    //   reverse rules,
+                                                    //   and a list of UnicodeSets encountered.
+
+    /**
+     * Return a rules string without unnecessary
+     * characters.
+     */
+    static UnicodeString stripRules(const UnicodeString &rules);
+private:
+
+    UBool       doParseActions(int32_t a);
+    void        error(UErrorCode e);                   // error reporting convenience function.
+    void        fixOpStack(RBBINode::OpPrecedence p);
+                                                       //   a character.
+    void        findSetFor(const UnicodeString &s, RBBINode *node, UnicodeSet *setToAdopt = NULL);
+
+    UChar32     nextCharLL();
+#ifdef RBBI_DEBUG
+    void        printNodeStack(const char *title);
+#endif
+    RBBINode    *pushNewNode(RBBINode::NodeType  t);
+    void        scanSet();
+
+
+    RBBIRuleBuilder               *fRB;              // The rule builder that we are part of.
+
+    int32_t                       fScanIndex;        // Index of current character being processed
+                                                     //   in the rule input string.
+    int32_t                       fNextIndex;        // Index of the next character, which
+                                                     //   is the first character not yet scanned.
+    UBool                         fQuoteMode;        // Scan is in a 'quoted region'
+    int32_t                       fLineNum;          // Line number in input file.
+    int32_t                       fCharNum;          // Char position within the line.
+    UChar32                       fLastChar;         // Previous char, needed to count CR-LF
+                                                     //   as a single line, not two.
+
+    RBBIRuleChar                  fC;                // Current char for parse state machine
+                                                     //   processing.
+    UnicodeString                 fVarName;          // $variableName, valid when we've just
+                                                     //   scanned one.
+
+    RBBIRuleTableEl               **fStateTable;     // State Transition Table for RBBI Rule
+                                                     //   parsing.  index by p[state][char-class]
+
+    uint16_t                      fStack[kStackSize];  // State stack, holds state pushes
+    int32_t                       fStackPtr;           //  and pops as specified in the state
+                                                       //  transition rules.
+
+    RBBINode                      *fNodeStack[kStackSize]; // Node stack, holds nodes created
+                                                           //  during the parse of a rule
+    int32_t                        fNodeStackPtr;
+
+
+    UBool                          fReverseRule;     // True if the rule currently being scanned
+                                                     //  is a reverse direction rule (if it
+                                                     //  starts with a '!')
+
+    UBool                          fLookAheadRule;   // True if the rule includes a '/'
+                                                     //   somewhere within it.
+
+    RBBISymbolTable               *fSymbolTable;     // symbol table, holds definitions of
+                                                     //   $variable symbols.
+
+    UHashtable                    *fSetTable;        // UnicocodeSet hash table, holds indexes to
+                                                     //   the sets created while parsing rules.
+                                                     //   The key is the string used for creating
+                                                     //   the set.
+
+    UnicodeSet                     fRuleSets[10];    // Unicode Sets that are needed during
+                                                     //  the scanning of RBBI rules.  The
+                                                     //  indicies for these are assigned by the
+                                                     //  perl script that builds the state tables.
+                                                     //  See rbbirpt.h.
+
+    int32_t                        fRuleNum;         // Counts each rule as it is scanned.
+
+    int32_t                        fOptionStart;     // Input index of start of a !!option
+                                                     //   keyword, while being scanned.
+
+    UnicodeSet *gRuleSet_rule_char;
+    UnicodeSet *gRuleSet_white_space;
+    UnicodeSet *gRuleSet_name_char;
+    UnicodeSet *gRuleSet_name_start_char;
+
+    RBBIRuleScanner(const RBBIRuleScanner &other); // forbid copying of this class
+    RBBIRuleScanner &operator=(const RBBIRuleScanner &other); // forbid copying of this class
+};
+
+U_NAMESPACE_END
+
+#endif
diff --git a/icu/source/common/rbbisetb.cpp b/icu/source/common/rbbisetb.cpp
new file mode 100644
index 0000000..cd855f7
--- /dev/null
+++ b/icu/source/common/rbbisetb.cpp
@@ -0,0 +1,695 @@
+//
+//  rbbisetb.cpp
+//
+/*
+***************************************************************************
+*   Copyright (C) 2002-2008 International Business Machines Corporation   *
+*   and others. All rights reserved.                                      *
+***************************************************************************
+*/
+//
+//  RBBISetBuilder   Handles processing of Unicode Sets from RBBI rules
+//                   (part of the rule building process.)
+//
+//      Starting with the rules parse tree from the scanner,
+//
+//                   -  Enumerate the set of UnicodeSets that are referenced
+//                      by the RBBI rules.
+//                   -  compute a set of non-overlapping character ranges
+//                      with all characters within a range belonging to the same
+//                      set of input uniocde sets.
+//                   -  Derive a set of non-overlapping UnicodeSet (like things)
+//                      that will correspond to columns in the state table for
+//                      the RBBI execution engine.  All characters within one
+//                      of these sets belong to the same set of the original
+//                      UnicodeSets from the user's rules.
+//                   -  construct the trie table that maps input characters
+//                      to the index of the matching non-overlapping set of set from
+//                      the previous step.
+//
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/uniset.h"
+#include "utrie.h"
+#include "uvector.h"
+#include "uassert.h"
+#include "cmemory.h"
+#include "cstring.h"
+
+#include "rbbisetb.h"
+#include "rbbinode.h"
+
+
+//------------------------------------------------------------------------
+//
+//   getFoldedRBBIValue        Call-back function used during building of Trie table.
+//                             Folding value: just store the offset (16 bits)
+//                             if there is any non-0 entry.
+//                             (It'd really be nice if the Trie builder would provide a
+//                             simple default, so this function could go away from here.)
+//
+//------------------------------------------------------------------------
+/* folding value: just store the offset (16 bits) if there is any non-0 entry */
+U_CDECL_BEGIN
+static uint32_t U_CALLCONV
+getFoldedRBBIValue(UNewTrie *trie, UChar32 start, int32_t offset) {
+    uint32_t value;
+    UChar32 limit;
+    UBool inBlockZero;
+
+    limit=start+0x400;
+    while(start<limit) {
+        value=utrie_get32(trie, start, &inBlockZero);
+        if(inBlockZero) {
+            start+=UTRIE_DATA_BLOCK_LENGTH;
+        } else if(value!=0) {
+            return (uint32_t)(offset|0x8000);
+        } else {
+            ++start;
+        }
+    }
+    return 0;
+}
+
+
+U_CDECL_END
+
+
+
+U_NAMESPACE_BEGIN
+
+//------------------------------------------------------------------------
+//
+//   Constructor
+//
+//------------------------------------------------------------------------
+RBBISetBuilder::RBBISetBuilder(RBBIRuleBuilder *rb)
+{
+    fRB             = rb;
+    fStatus         = rb->fStatus;
+    fRangeList      = 0;
+    fTrie           = 0;
+    fTrieSize       = 0;
+    fGroupCount     = 0;
+    fSawBOF         = FALSE;
+}
+
+
+//------------------------------------------------------------------------
+//
+//   Destructor
+//
+//------------------------------------------------------------------------
+RBBISetBuilder::~RBBISetBuilder()
+{
+    RangeDescriptor   *nextRangeDesc;
+
+    // Walk through & delete the linked list of RangeDescriptors
+    for (nextRangeDesc = fRangeList; nextRangeDesc!=NULL;) {
+        RangeDescriptor *r = nextRangeDesc;
+        nextRangeDesc      = r->fNext;
+        delete r;
+    }
+
+    utrie_close(fTrie);
+}
+
+
+
+
+//------------------------------------------------------------------------
+//
+//   build          Build the list of non-overlapping character ranges
+//                  from the Unicode Sets.
+//
+//------------------------------------------------------------------------
+void RBBISetBuilder::build() {
+    RBBINode        *usetNode;
+    RangeDescriptor *rlRange;
+
+    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "usets")) {printSets();}
+
+    //
+    //  Initialize the process by creating a single range encompassing all characters
+    //  that is in no sets.
+    //
+    fRangeList                = new RangeDescriptor(*fStatus); // will check for status here
+    if (fRangeList == NULL) {
+        *fStatus = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    fRangeList->fStartChar    = 0;
+    fRangeList->fEndChar      = 0x10ffff;
+
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+
+    //
+    //  Find the set of non-overlapping ranges of characters
+    //
+    int  ni;
+    for (ni=0; ; ni++) {        // Loop over each of the UnicodeSets encountered in the input rules
+        usetNode = (RBBINode *)this->fRB->fUSetNodes->elementAt(ni);
+        if (usetNode==NULL) {
+            break;
+        }
+
+        UnicodeSet      *inputSet             = usetNode->fInputSet;
+        int32_t          inputSetRangeCount   = inputSet->getRangeCount();
+        int              inputSetRangeIndex   = 0;
+                         rlRange              = fRangeList;
+
+        for (;;) {
+            if (inputSetRangeIndex >= inputSetRangeCount) {
+                break;
+            }
+            UChar32      inputSetRangeBegin  = inputSet->getRangeStart(inputSetRangeIndex);
+            UChar32      inputSetRangeEnd    = inputSet->getRangeEnd(inputSetRangeIndex);
+
+            // skip over ranges from the range list that are completely
+            //   below the current range from the input unicode set.
+            while (rlRange->fEndChar < inputSetRangeBegin) {
+                rlRange = rlRange->fNext;
+            }
+
+            // If the start of the range from the range list is before with
+            //   the start of the range from the unicode set, split the range list range
+            //   in two, with one part being before (wholly outside of) the unicode set
+            //   and the other containing the rest.
+            //   Then continue the loop; the post-split current range will then be skipped
+            //     over
+            if (rlRange->fStartChar < inputSetRangeBegin) {
+                rlRange->split(inputSetRangeBegin, *fStatus);
+                if (U_FAILURE(*fStatus)) {
+                    return;
+                }
+                continue;
+            }
+
+            // Same thing at the end of the ranges...
+            // If the end of the range from the range list doesn't coincide with
+            //   the end of the range from the unicode set, split the range list
+            //   range in two.  The first part of the split range will be
+            //   wholly inside the Unicode set.
+            if (rlRange->fEndChar > inputSetRangeEnd) {
+                rlRange->split(inputSetRangeEnd+1, *fStatus);
+                if (U_FAILURE(*fStatus)) {
+                    return;
+                }
+            }
+
+            // The current rlRange is now entirely within the UnicodeSet range.
+            // Add this unicode set to the list of sets for this rlRange
+            if (rlRange->fIncludesSets->indexOf(usetNode) == -1) {
+                rlRange->fIncludesSets->addElement(usetNode, *fStatus);
+                if (U_FAILURE(*fStatus)) {
+                    return;
+                }
+            }
+
+            // Advance over ranges that we are finished with.
+            if (inputSetRangeEnd == rlRange->fEndChar) {
+                inputSetRangeIndex++;
+            }
+            rlRange = rlRange->fNext;
+        }
+    }
+
+    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "range")) { printRanges();}
+
+    //
+    //  Group the above ranges, with each group consisting of one or more
+    //    ranges that are in exactly the same set of original UnicodeSets.
+    //    The groups are numbered, and these group numbers are the set of
+    //    input symbols recognized by the run-time state machine.
+    //
+    //    Numbering: # 0  (state table column 0) is unused.
+    //               # 1  is reserved - table column 1 is for end-of-input
+    //               # 2  is reserved - table column 2 is for beginning-in-input
+    //               # 3  is the first range list.
+    //
+    RangeDescriptor *rlSearchRange;
+    for (rlRange = fRangeList; rlRange!=0; rlRange=rlRange->fNext) {
+        for (rlSearchRange=fRangeList; rlSearchRange != rlRange; rlSearchRange=rlSearchRange->fNext) {
+            if (rlRange->fIncludesSets->equals(*rlSearchRange->fIncludesSets)) {
+                rlRange->fNum = rlSearchRange->fNum;
+                break;
+            }
+        }
+        if (rlRange->fNum == 0) {
+            fGroupCount ++;
+            rlRange->fNum = fGroupCount+2; 
+            rlRange->setDictionaryFlag();
+            addValToSets(rlRange->fIncludesSets, fGroupCount+2);
+        }
+    }
+
+    // Handle input sets that contain the special string {eof}.
+    //   Column 1 of the state table is reserved for EOF on input.
+    //   Column 2 is reserved for before-the-start-input.
+    //            (This column can be optimized away later if there are no rule
+    //             references to {bof}.)
+    //   Add this column value (1 or 2) to the equivalent expression
+    //     subtree for each UnicodeSet that contains the string {eof}
+    //   Because {bof} and {eof} are not a characters in the normal sense,
+    //   they doesn't affect the computation of ranges or TRIE.
+    static const UChar eofUString[] = {0x65, 0x6f, 0x66, 0};
+    static const UChar bofUString[] = {0x62, 0x6f, 0x66, 0};
+
+    UnicodeString eofString(eofUString);
+    UnicodeString bofString(bofUString);
+    for (ni=0; ; ni++) {        // Loop over each of the UnicodeSets encountered in the input rules
+        usetNode = (RBBINode *)this->fRB->fUSetNodes->elementAt(ni);
+        if (usetNode==NULL) {
+            break;
+        }
+        UnicodeSet      *inputSet = usetNode->fInputSet;
+        if (inputSet->contains(eofString)) {
+            addValToSet(usetNode, 1);
+        }
+        if (inputSet->contains(bofString)) {
+            addValToSet(usetNode, 2);
+            fSawBOF = TRUE;
+        }
+    }
+
+
+    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "rgroup")) {printRangeGroups();}
+    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "esets")) {printSets();}
+
+    //
+    // Build the Trie table for mapping UChar32 values to the corresponding
+    //   range group number
+    //
+    fTrie = utrie_open(NULL,    //  Pre-existing trie to be filled in
+                      NULL,    //  Data array  (utrie will allocate one)
+                      100000,  //  Max Data Length
+                      0,       //  Initial value for all code points
+                      0,       //  Lead surrogate unit value
+                      TRUE);   //  Keep Latin 1 in separately
+
+
+    for (rlRange = fRangeList; rlRange!=0; rlRange=rlRange->fNext) {
+        utrie_setRange32(fTrie, rlRange->fStartChar, rlRange->fEndChar+1, rlRange->fNum, TRUE);
+    }
+}
+
+
+
+//-----------------------------------------------------------------------------------
+//
+//  getTrieSize()    Return the size that will be required to serialize the Trie.
+//
+//-----------------------------------------------------------------------------------
+int32_t RBBISetBuilder::getTrieSize() /*const*/ {
+    fTrieSize  = utrie_serialize(fTrie,
+                                    NULL,                // Buffer
+                                    0,                   // Capacity
+                                    getFoldedRBBIValue,
+                                    TRUE,                // Reduce to 16 bits
+                                    fStatus);
+    // RBBIDebugPrintf("Trie table size is %d\n", trieSize);
+    return fTrieSize;
+}
+
+
+//-----------------------------------------------------------------------------------
+//
+//  serializeTrie()   Put the serialized trie at the specified address.
+//                    Trust the caller to have given us enough memory.
+//                    getTrieSize() MUST be called first.
+//
+//-----------------------------------------------------------------------------------
+void RBBISetBuilder::serializeTrie(uint8_t *where) {
+    utrie_serialize(fTrie,
+                    where,                   // Buffer
+                    fTrieSize,               // Capacity
+                    getFoldedRBBIValue,
+                    TRUE,                    // Reduce to 16 bits
+                    fStatus);
+}
+
+//------------------------------------------------------------------------
+//
+//  addValToSets     Add a runtime-mapped input value to each uset from a
+//                   list of uset nodes. (val corresponds to a state table column.)
+//                   For each of the original Unicode sets - which correspond
+//                   directly to uset nodes - a logically equivalent expression
+//                   is constructed in terms of the remapped runtime input
+//                   symbol set.  This function adds one runtime input symbol to
+//                   a list of sets.
+//
+//                   The "logically equivalent expression" is the tree for an
+//                   or-ing together of all of the symbols that go into the set.
+//
+//------------------------------------------------------------------------
+void  RBBISetBuilder::addValToSets(UVector *sets, uint32_t val) {
+    int32_t       ix;
+
+    for (ix=0; ix<sets->size(); ix++) {
+        RBBINode *usetNode = (RBBINode *)sets->elementAt(ix);
+        addValToSet(usetNode, val);
+    }
+}
+
+void  RBBISetBuilder::addValToSet(RBBINode *usetNode, uint32_t val) {
+    RBBINode *leafNode = new RBBINode(RBBINode::leafChar);
+    if (leafNode == NULL) {
+        *fStatus = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    leafNode->fVal = (unsigned short)val;
+    if (usetNode->fLeftChild == NULL) {
+        usetNode->fLeftChild = leafNode;
+        leafNode->fParent    = usetNode;
+    } else {
+        // There are already input symbols present for this set.
+        // Set up an OR node, with the previous stuff as the left child
+        //   and the new value as the right child.
+        RBBINode *orNode = new RBBINode(RBBINode::opOr);
+        if (orNode == NULL) {
+            *fStatus = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+        orNode->fLeftChild  = usetNode->fLeftChild;
+        orNode->fRightChild = leafNode;
+        orNode->fLeftChild->fParent  = orNode;
+        orNode->fRightChild->fParent = orNode;
+        usetNode->fLeftChild = orNode;
+        orNode->fParent = usetNode;
+    }
+}
+
+
+//------------------------------------------------------------------------
+//
+//   getNumCharCategories
+//
+//------------------------------------------------------------------------
+int32_t  RBBISetBuilder::getNumCharCategories() const {
+    return fGroupCount + 3;
+}
+
+
+//------------------------------------------------------------------------
+//
+//   sawBOF
+//
+//------------------------------------------------------------------------
+UBool  RBBISetBuilder::sawBOF() const {
+    return fSawBOF;
+}
+
+
+//------------------------------------------------------------------------
+//
+//   getFirstChar      Given a runtime RBBI character category, find
+//                     the first UChar32 that is in the set of chars 
+//                     in the category.
+//------------------------------------------------------------------------
+UChar32  RBBISetBuilder::getFirstChar(int32_t category) const {
+    RangeDescriptor   *rlRange;
+    UChar32            retVal = (UChar32)-1;
+    for (rlRange = fRangeList; rlRange!=0; rlRange=rlRange->fNext) {
+        if (rlRange->fNum == category) {
+            retVal = rlRange->fStartChar;
+            break;
+        }
+    }
+    return retVal;
+}
+
+
+
+//------------------------------------------------------------------------
+//
+//   printRanges        A debugging function.
+//                      dump out all of the range definitions.
+//
+//------------------------------------------------------------------------
+#ifdef RBBI_DEBUG
+void RBBISetBuilder::printRanges() {
+    RangeDescriptor       *rlRange;
+    int                    i;
+
+    RBBIDebugPrintf("\n\n Nonoverlapping Ranges ...\n");
+    for (rlRange = fRangeList; rlRange!=0; rlRange=rlRange->fNext) {
+        RBBIDebugPrintf("%2i  %4x-%4x  ", rlRange->fNum, rlRange->fStartChar, rlRange->fEndChar);
+
+        for (i=0; i<rlRange->fIncludesSets->size(); i++) {
+            RBBINode       *usetNode    = (RBBINode *)rlRange->fIncludesSets->elementAt(i);
+            UnicodeString   setName = UNICODE_STRING("anon", 4);
+            RBBINode       *setRef = usetNode->fParent;
+            if (setRef != NULL) {
+                RBBINode *varRef = setRef->fParent;
+                if (varRef != NULL  &&  varRef->fType == RBBINode::varRef) {
+                    setName = varRef->fText;
+                }
+            }
+            RBBI_DEBUG_printUnicodeString(setName); RBBIDebugPrintf("  ");
+        }
+        RBBIDebugPrintf("\n");
+    }
+}
+#endif
+
+
+//------------------------------------------------------------------------
+//
+//   printRangeGroups     A debugging function.
+//                        dump out all of the range groups.
+//
+//------------------------------------------------------------------------
+#ifdef RBBI_DEBUG
+void RBBISetBuilder::printRangeGroups() {
+    RangeDescriptor       *rlRange;
+    RangeDescriptor       *tRange;
+    int                    i;
+    int                    lastPrintedGroupNum = 0;
+
+    RBBIDebugPrintf("\nRanges grouped by Unicode Set Membership...\n");
+    for (rlRange = fRangeList; rlRange!=0; rlRange=rlRange->fNext) {
+        int groupNum = rlRange->fNum & 0xbfff;
+        if (groupNum > lastPrintedGroupNum) {
+            lastPrintedGroupNum = groupNum;
+            RBBIDebugPrintf("%2i  ", groupNum);
+
+            if (rlRange->fNum & 0x4000) { RBBIDebugPrintf(" <DICT> ");}
+
+            for (i=0; i<rlRange->fIncludesSets->size(); i++) {
+                RBBINode       *usetNode    = (RBBINode *)rlRange->fIncludesSets->elementAt(i);
+                UnicodeString   setName = UNICODE_STRING("anon", 4);
+                RBBINode       *setRef = usetNode->fParent;
+                if (setRef != NULL) {
+                    RBBINode *varRef = setRef->fParent;
+                    if (varRef != NULL  &&  varRef->fType == RBBINode::varRef) {
+                        setName = varRef->fText;
+                    }
+                }
+                RBBI_DEBUG_printUnicodeString(setName); RBBIDebugPrintf(" ");
+            }
+
+            i = 0;
+            for (tRange = rlRange; tRange != 0; tRange = tRange->fNext) {
+                if (tRange->fNum == rlRange->fNum) {
+                    if (i++ % 5 == 0) {
+                        RBBIDebugPrintf("\n    ");
+                    }
+                    RBBIDebugPrintf("  %05x-%05x", tRange->fStartChar, tRange->fEndChar);
+                }
+            }
+            RBBIDebugPrintf("\n");
+        }
+    }
+    RBBIDebugPrintf("\n");
+}
+#endif
+
+
+//------------------------------------------------------------------------
+//
+//   printSets          A debugging function.
+//                      dump out all of the set definitions.
+//
+//------------------------------------------------------------------------
+#ifdef RBBI_DEBUG
+void RBBISetBuilder::printSets() {
+    int                   i;
+
+    RBBIDebugPrintf("\n\nUnicode Sets List\n------------------\n");
+    for (i=0; ; i++) {
+        RBBINode        *usetNode;
+        RBBINode        *setRef;
+        RBBINode        *varRef;
+        UnicodeString    setName;
+
+        usetNode = (RBBINode *)fRB->fUSetNodes->elementAt(i);
+        if (usetNode == NULL) {
+            break;
+        }
+
+        RBBIDebugPrintf("%3d    ", i);
+        setName = UNICODE_STRING("anonymous", 9);
+        setRef = usetNode->fParent;
+        if (setRef != NULL) {
+            varRef = setRef->fParent;
+            if (varRef != NULL  &&  varRef->fType == RBBINode::varRef) {
+                setName = varRef->fText;
+            }
+        }
+        RBBI_DEBUG_printUnicodeString(setName);
+        RBBIDebugPrintf("   ");
+        RBBI_DEBUG_printUnicodeString(usetNode->fText);
+        RBBIDebugPrintf("\n");
+        if (usetNode->fLeftChild != NULL) {
+            usetNode->fLeftChild->printTree(TRUE);
+        }
+    }
+    RBBIDebugPrintf("\n");
+}
+#endif
+
+
+
+//-------------------------------------------------------------------------------------
+//
+//  RangeDescriptor copy constructor
+//
+//-------------------------------------------------------------------------------------
+
+RangeDescriptor::RangeDescriptor(const RangeDescriptor &other, UErrorCode &status) {
+    int  i;
+
+    this->fStartChar    = other.fStartChar;
+    this->fEndChar      = other.fEndChar;
+    this->fNum          = other.fNum;
+    this->fNext         = NULL;
+    UErrorCode oldstatus = status;
+    this->fIncludesSets = new UVector(status);
+    if (U_FAILURE(oldstatus)) {
+        status = oldstatus;
+    }
+    if (U_FAILURE(status)) {
+        return;
+    }
+    /* test for NULL */
+    if (this->fIncludesSets == 0) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+
+    for (i=0; i<other.fIncludesSets->size(); i++) {
+        this->fIncludesSets->addElement(other.fIncludesSets->elementAt(i), status);
+    }
+}
+
+
+//-------------------------------------------------------------------------------------
+//
+//  RangeDesriptor default constructor
+//
+//-------------------------------------------------------------------------------------
+RangeDescriptor::RangeDescriptor(UErrorCode &status) {
+    this->fStartChar    = 0;
+    this->fEndChar      = 0;
+    this->fNum          = 0;
+    this->fNext         = NULL;
+    UErrorCode oldstatus = status;
+    this->fIncludesSets = new UVector(status);
+    if (U_FAILURE(oldstatus)) {
+        status = oldstatus;
+    }
+    if (U_FAILURE(status)) {
+        return;
+    }
+    /* test for NULL */
+    if(this->fIncludesSets == 0) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+
+}
+
+
+//-------------------------------------------------------------------------------------
+//
+//  RangeDesriptor Destructor
+//
+//-------------------------------------------------------------------------------------
+RangeDescriptor::~RangeDescriptor() {
+    delete  fIncludesSets;
+    fIncludesSets = NULL;
+}
+
+//-------------------------------------------------------------------------------------
+//
+//  RangeDesriptor::split()
+//
+//-------------------------------------------------------------------------------------
+void RangeDescriptor::split(UChar32 where, UErrorCode &status) {
+    U_ASSERT(where>fStartChar && where<=fEndChar);
+    RangeDescriptor *nr = new RangeDescriptor(*this, status);
+    if(nr == 0) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    if (U_FAILURE(status)) {
+        delete nr;
+        return;
+    }
+    //  RangeDescriptor copy constructor copies all fields.
+    //  Only need to update those that are different after the split.
+    nr->fStartChar = where;
+    this->fEndChar = where-1;
+    nr->fNext      = this->fNext;
+    this->fNext    = nr;
+}
+
+
+//-------------------------------------------------------------------------------------
+//
+//   RangeDescriptor::setDictionaryFlag
+//
+//            Character Category Numbers that include characters from
+//            the original Unicode Set named "dictionary" have bit 14
+//            set to 1.  The RBBI runtime engine uses this to trigger
+//            use of the word dictionary.
+//
+//            This function looks through the Unicode Sets that it
+//            (the range) includes, and sets the bit in fNum when
+//            "dictionary" is among them.
+//
+//            TODO:  a faster way would be to find the set node for
+//                   "dictionary" just once, rather than looking it
+//                   up by name every time.
+//
+//-------------------------------------------------------------------------------------
+void RangeDescriptor::setDictionaryFlag() {
+    int i;
+
+    for (i=0; i<this->fIncludesSets->size(); i++) {
+        RBBINode       *usetNode    = (RBBINode *)fIncludesSets->elementAt(i);
+        UnicodeString   setName;
+        RBBINode       *setRef = usetNode->fParent;
+        if (setRef != NULL) {
+            RBBINode *varRef = setRef->fParent;
+            if (varRef != NULL  &&  varRef->fType == RBBINode::varRef) {
+                setName = varRef->fText;
+            }
+        }
+        if (setName.compare(UNICODE_STRING("dictionary", 10)) == 0) {   // TODO:  no string literals.
+            this->fNum |= 0x4000;
+            break;
+        }
+    }
+}
+
+
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/icu/source/common/rbbisetb.h b/icu/source/common/rbbisetb.h
new file mode 100644
index 0000000..c8bc1df
--- /dev/null
+++ b/icu/source/common/rbbisetb.h
@@ -0,0 +1,130 @@
+//
+//  rbbisetb.h
+/*
+**********************************************************************
+*   Copyright (c) 2001-2005, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*/
+
+#ifndef RBBISETB_H
+#define RBBISETB_H
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+#include "rbbirb.h"
+#include "uvector.h"
+
+struct  UNewTrie;
+
+U_NAMESPACE_BEGIN
+
+//
+//  RBBISetBuilder   Derives the character categories used by the runtime RBBI engine
+//                   from the Unicode Sets appearing in the source  RBBI rules, and
+//                   creates the TRIE table used to map from Unicode to the
+//                   character categories.
+//
+
+
+//
+//  RangeDescriptor
+//
+//     Each of the non-overlapping character ranges gets one of these descriptors.
+//     All of them are strung together in a linked list, which is kept in order
+//     (by character)
+//
+class RangeDescriptor : public UMemory {
+public:
+    UChar32            fStartChar;      // Start of range, unicode 32 bit value.
+    UChar32            fEndChar;        // End of range, unicode 32 bit value.
+    int32_t            fNum;            // runtime-mapped input value for this range.
+    UVector           *fIncludesSets;   // vector of the the original
+                                        //   Unicode sets that include this range.
+                                        //    (Contains ptrs to uset nodes)
+    RangeDescriptor   *fNext;           // Next RangeDescriptor in the linked list.
+
+    RangeDescriptor(UErrorCode &status);
+    RangeDescriptor(const RangeDescriptor &other, UErrorCode &status);
+    ~RangeDescriptor();
+    void split(UChar32 where, UErrorCode &status);   // Spit this range in two at "where", with
+                                        //   where appearing in the second (higher) part.
+    void setDictionaryFlag();           // Check whether this range appears as part of
+                                        //   the Unicode set named "dictionary"
+
+private:
+    RangeDescriptor(const RangeDescriptor &other); // forbid copying of this class
+    RangeDescriptor &operator=(const RangeDescriptor &other); // forbid copying of this class
+};
+
+
+//
+//  RBBISetBuilder   Handles processing of Unicode Sets from RBBI rules.
+//
+//      Starting with the rules parse tree from the scanner,
+//
+//                   -  Enumerate the set of UnicodeSets that are referenced
+//                      by the RBBI rules.
+//                   -  compute a derived set of non-overlapping UnicodeSets
+//                      that will correspond to columns in the state table for
+//                      the RBBI execution engine.
+//                   -  construct the trie table that maps input characters
+//                      to set numbers in the non-overlapping set of sets.
+//
+
+
+class RBBISetBuilder : public UMemory {
+public:
+    RBBISetBuilder(RBBIRuleBuilder *rb);
+    ~RBBISetBuilder();
+
+    void     build();
+    void     addValToSets(UVector *sets,      uint32_t val);
+    void     addValToSet (RBBINode *usetNode, uint32_t val);
+    int32_t  getNumCharCategories() const;   // CharCategories are the same as input symbol set to the
+                                             //    runtime state machine, which are the same as
+                                             //    columns in the DFA state table
+    int32_t  getTrieSize() /*const*/;        // Size in bytes of the serialized Trie.
+    void     serializeTrie(uint8_t *where);  // write out the serialized Trie.
+    UChar32  getFirstChar(int32_t  val) const;
+    UBool    sawBOF() const;                 // Indicate whether any references to the {bof} pseudo
+                                             //   character were encountered.
+#ifdef RBBI_DEBUG
+    void     printSets();
+    void     printRanges();
+    void     printRangeGroups();
+#else
+    #define printSets()
+    #define printRanges()
+    #define printRangeGroups()
+#endif
+
+private:
+    void           numberSets();
+
+    RBBIRuleBuilder       *fRB;             // The RBBI Rule Compiler that owns us.
+    UErrorCode            *fStatus;
+
+    RangeDescriptor       *fRangeList;      // Head of the linked list of RangeDescriptors
+
+    UNewTrie              *fTrie;           // The mapping TRIE that is the end result of processing
+    uint32_t              fTrieSize;        //  the Unicode Sets.
+
+    // Groups correspond to character categories -
+    //       groups of ranges that are in the same original UnicodeSets.
+    //       fGroupCount is the index of the last used group.
+    //       fGroupCount+1 is also the number of columns in the RBBI state table being compiled.
+    //       State table column 0 is not used.  Column 1 is for end-of-input.
+    //       column 2 is for group 0.  Funny counting.
+    int32_t               fGroupCount;
+
+    UBool                 fSawBOF;
+
+    RBBISetBuilder(const RBBISetBuilder &other); // forbid copying of this class
+    RBBISetBuilder &operator=(const RBBISetBuilder &other); // forbid copying of this class
+};
+
+
+
+U_NAMESPACE_END
+#endif
diff --git a/icu/source/common/rbbistbl.cpp b/icu/source/common/rbbistbl.cpp
new file mode 100644
index 0000000..cbcd381
--- /dev/null
+++ b/icu/source/common/rbbistbl.cpp
@@ -0,0 +1,269 @@
+//
+//  file:  rbbistbl.cpp    Implementation of the ICU RBBISymbolTable class
+//
+/*
+***************************************************************************
+*   Copyright (C) 2002-2006 International Business Machines Corporation   *
+*   and others. All rights reserved.                                      *
+***************************************************************************
+*/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/unistr.h"
+#include "unicode/uniset.h"
+#include "unicode/uchar.h"
+#include "unicode/parsepos.h"
+
+#include "umutex.h"
+
+#include "rbbirb.h"
+#include "rbbinode.h"
+
+
+//
+//  RBBISymbolTableEntry_deleter    Used by the UHashTable to delete the contents
+//                                  when the hash table is deleted.
+//
+U_CDECL_BEGIN
+static void U_CALLCONV RBBISymbolTableEntry_deleter(void *p) {
+    U_NAMESPACE_QUALIFIER RBBISymbolTableEntry *px = (U_NAMESPACE_QUALIFIER RBBISymbolTableEntry *)p;
+    delete px;
+}
+U_CDECL_END
+
+
+
+U_NAMESPACE_BEGIN
+
+RBBISymbolTable::RBBISymbolTable(RBBIRuleScanner *rs, const UnicodeString &rules, UErrorCode &status)
+    :fRules(rules), fRuleScanner(rs), ffffString(UChar(0xffff))
+{
+    fHashTable       = NULL;
+    fCachedSetLookup = NULL;
+    
+    fHashTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, &status);
+    // uhash_open checks status
+    if (U_FAILURE(status)) {
+        return;
+    }
+    uhash_setValueDeleter(fHashTable, RBBISymbolTableEntry_deleter);
+}
+
+
+
+RBBISymbolTable::~RBBISymbolTable()
+{
+    uhash_close(fHashTable);
+}
+
+
+//
+//  RBBISymbolTable::lookup       This function from the abstract symbol table inteface
+//                                looks up a variable name and returns a UnicodeString
+//                                containing the substitution text.
+//
+//                                The variable name does NOT include the leading $.
+//
+const UnicodeString  *RBBISymbolTable::lookup(const UnicodeString& s) const
+{
+    RBBISymbolTableEntry  *el;
+    RBBINode              *varRefNode;
+    RBBINode              *exprNode;
+    RBBINode              *usetNode;
+    const UnicodeString   *retString;
+    RBBISymbolTable       *This = (RBBISymbolTable *)this;   // cast off const
+
+    el = (RBBISymbolTableEntry *)uhash_get(fHashTable, &s);
+    if (el == NULL) {
+        return NULL;
+    }
+
+    varRefNode = el->val;
+    exprNode   = varRefNode->fLeftChild;     // Root node of expression for variable
+    if (exprNode->fType == RBBINode::setRef) {
+        // The $variable refers to a single UnicodeSet
+        //   return the ffffString, which will subsequently be interpreted as a
+        //   stand-in character for the set by RBBISymbolTable::lookupMatcher()
+        usetNode = exprNode->fLeftChild;
+        This->fCachedSetLookup = usetNode->fInputSet;
+        retString = &ffffString;
+    }
+    else
+    {
+        // The variable refers to something other than just a set.
+        // return the original source string for the expression
+        retString = &exprNode->fText;
+        This->fCachedSetLookup = NULL;
+    }
+    return retString;
+}
+
+
+
+//
+//  RBBISymbolTable::lookupMatcher   This function from the abstract symbol table
+//                                   interface maps a single stand-in character to a
+//                                   pointer to a Unicode Set.   The Unicode Set code uses this
+//                                   mechanism to get all references to the same $variable
+//                                   name to refer to a single common Unicode Set instance.
+//
+//    This implementation cheats a little, and does not maintain a map of stand-in chars
+//    to sets.  Instead, it takes advantage of the fact that  the UnicodeSet
+//    constructor will always call this function right after calling lookup(),
+//    and we just need to remember what set to return between these two calls.
+const UnicodeFunctor *RBBISymbolTable::lookupMatcher(UChar32 ch) const
+{
+    UnicodeSet *retVal = NULL;
+    RBBISymbolTable *This = (RBBISymbolTable *)this;   // cast off const
+    if (ch == 0xffff) {
+        retVal = fCachedSetLookup;
+        This->fCachedSetLookup = 0;
+    }
+    return retVal;
+}
+
+//
+// RBBISymbolTable::parseReference   This function from the abstract symbol table interface
+//                                   looks for a $variable name in the source text.
+//                                   It does not look it up, only scans for it.
+//                                   It is used by the UnicodeSet parser.
+//
+//                                   This implementation is lifted pretty much verbatim
+//                                   from the rules based transliterator implementation.
+//                                   I didn't see an obvious way of sharing it.
+//
+UnicodeString   RBBISymbolTable::parseReference(const UnicodeString& text,
+                                                ParsePosition& pos, int32_t limit) const
+{
+    int32_t start = pos.getIndex();
+    int32_t i = start;
+    UnicodeString result;
+    while (i < limit) {
+        UChar c = text.charAt(i);
+        if ((i==start && !u_isIDStart(c)) || !u_isIDPart(c)) {
+            break;
+        }
+        ++i;
+    }
+    if (i == start) { // No valid name chars
+        return result; // Indicate failure with empty string
+    }
+    pos.setIndex(i);
+    text.extractBetween(start, i, result);
+    return result;
+}
+
+
+
+//
+// RBBISymbolTable::lookupNode      Given a key (a variable name), return the
+//                                  corresponding RBBI Node.  If there is no entry
+//                                  in the table for this name, return NULL.
+//
+RBBINode       *RBBISymbolTable::lookupNode(const UnicodeString &key) const{
+
+    RBBINode             *retNode = NULL;
+    RBBISymbolTableEntry *el;
+
+    el = (RBBISymbolTableEntry *)uhash_get(fHashTable, &key);
+    if (el != NULL) {
+        retNode = el->val;
+    }
+    return retNode;
+}
+
+
+//
+//    RBBISymbolTable::addEntry     Add a new entry to the symbol table.
+//                                  Indicate an error if the name already exists -
+//                                    this will only occur in the case of duplicate
+//                                    variable assignments.
+//
+void            RBBISymbolTable::addEntry  (const UnicodeString &key, RBBINode *val, UErrorCode &err) {
+    RBBISymbolTableEntry *e;
+    /* test for buffer overflows */
+    if (U_FAILURE(err)) {
+        return;
+    }
+    e = (RBBISymbolTableEntry *)uhash_get(fHashTable, &key);
+    if (e != NULL) {
+        err = U_BRK_VARIABLE_REDFINITION;
+        return;
+    }
+
+    e = new RBBISymbolTableEntry;
+    if (e == NULL) {
+        err = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    e->key = key;
+    e->val = val;
+    uhash_put( fHashTable, &e->key, e, &err);
+}
+
+
+RBBISymbolTableEntry::RBBISymbolTableEntry() : UMemory(), key(), val(NULL) {}
+
+RBBISymbolTableEntry::~RBBISymbolTableEntry() {
+    // The "val" of a symbol table entry is a variable reference node.
+    // The l. child of the val is the rhs expression from the assignment.
+    // Unlike other node types, children of variable reference nodes are not
+    //    automatically recursively deleted.  We do it manually here.
+    delete val->fLeftChild;
+    val->fLeftChild = NULL;
+
+    delete  val;
+
+    // Note: the key UnicodeString is destructed by virtue of being in the object by value.
+}
+
+
+//
+//  RBBISymbolTable::print    Debugging function, dump out the symbol table contents.
+//
+#ifdef RBBI_DEBUG
+void RBBISymbolTable::rbbiSymtablePrint() const {
+    RBBIDebugPrintf("Variable Definitions\n"
+           "Name               Node Val     String Val\n"
+           "----------------------------------------------------------------------\n");
+
+    int32_t pos = -1;
+    const UHashElement  *e   = NULL;
+    for (;;) {
+        e = uhash_nextElement(fHashTable,  &pos);
+        if (e == NULL ) {
+            break;
+        }
+        RBBISymbolTableEntry  *s   = (RBBISymbolTableEntry *)e->value.pointer;
+
+        RBBI_DEBUG_printUnicodeString(s->key, 15);
+        RBBIDebugPrintf("   %8p   ", (void *)s->val);
+        RBBI_DEBUG_printUnicodeString(s->val->fLeftChild->fText);
+        RBBIDebugPrintf("\n");
+    }
+
+    RBBIDebugPrintf("\nParsed Variable Definitions\n");
+    pos = -1;
+    for (;;) {
+        e = uhash_nextElement(fHashTable,  &pos);
+        if (e == NULL ) {
+            break;
+        }
+        RBBISymbolTableEntry  *s   = (RBBISymbolTableEntry *)e->value.pointer;
+        RBBI_DEBUG_printUnicodeString(s->key);
+        s->val->fLeftChild->printTree(TRUE);
+        RBBIDebugPrintf("\n");
+    }
+}
+#endif
+
+
+
+
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/icu/source/common/rbbitblb.cpp b/icu/source/common/rbbitblb.cpp
new file mode 100644
index 0000000..2ce82df
--- /dev/null
+++ b/icu/source/common/rbbitblb.cpp
@@ -0,0 +1,1260 @@
+/*
+**********************************************************************
+*   Copyright (c) 2002-2009, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*/
+//
+//  rbbitblb.cpp
+//
+
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/unistr.h"
+#include "rbbitblb.h"
+#include "rbbirb.h"
+#include "rbbisetb.h"
+#include "rbbidata.h"
+#include "cstring.h"
+#include "uassert.h"
+#include "cmemory.h"
+
+U_NAMESPACE_BEGIN
+
+RBBITableBuilder::RBBITableBuilder(RBBIRuleBuilder *rb, RBBINode **rootNode) :
+ fTree(*rootNode) {
+    fRB                 = rb;
+    fStatus             = fRB->fStatus;
+    UErrorCode status   = U_ZERO_ERROR;
+    fDStates            = new UVector(status);
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+    if (U_FAILURE(status)) {
+        *fStatus = status;
+        return;
+    }
+    if (fDStates == NULL) {
+        *fStatus = U_MEMORY_ALLOCATION_ERROR;;
+    }
+}
+
+
+
+RBBITableBuilder::~RBBITableBuilder() {
+    int i;
+    for (i=0; i<fDStates->size(); i++) {
+        delete (RBBIStateDescriptor *)fDStates->elementAt(i);
+    }
+    delete   fDStates;
+}
+
+
+//-----------------------------------------------------------------------------
+//
+//   RBBITableBuilder::build  -  This is the main function for building the DFA state transtion
+//                               table from the RBBI rules parse tree.
+//
+//-----------------------------------------------------------------------------
+void  RBBITableBuilder::build() {
+
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+
+    // If there were no rules, just return.  This situation can easily arise
+    //   for the reverse rules.
+    if (fTree==NULL) {
+        return;
+    }
+
+    //
+    // Walk through the tree, replacing any references to $variables with a copy of the
+    //   parse tree for the substition expression.
+    //
+    fTree = fTree->flattenVariables();
+#ifdef RBBI_DEBUG
+    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "ftree")) {
+        RBBIDebugPuts("Parse tree after flattening variable references.");
+        fTree->printTree(TRUE);
+    }
+#endif
+
+    //
+    // If the rules contained any references to {bof} 
+    //   add a {bof} <cat> <former root of tree> to the
+    //   tree.  Means that all matches must start out with the 
+    //   {bof} fake character.
+    // 
+    if (fRB->fSetBuilder->sawBOF()) {
+        RBBINode *bofTop    = new RBBINode(RBBINode::opCat);
+        RBBINode *bofLeaf   = new RBBINode(RBBINode::leafChar);
+        // Delete and exit if memory allocation failed.
+        if (bofTop == NULL || bofLeaf == NULL) {
+            *fStatus = U_MEMORY_ALLOCATION_ERROR;
+            delete bofTop;
+            delete bofLeaf;
+            return;
+        }
+        bofTop->fLeftChild  = bofLeaf;
+        bofTop->fRightChild = fTree;
+        bofLeaf->fParent    = bofTop;
+        bofLeaf->fVal       = 2;      // Reserved value for {bof}.
+        fTree               = bofTop;
+    }
+
+    //
+    // Add a unique right-end marker to the expression.
+    //   Appears as a cat-node, left child being the original tree,
+    //   right child being the end marker.
+    //
+    RBBINode *cn = new RBBINode(RBBINode::opCat);
+    // Exit if memory allocation failed.
+    if (cn == NULL) {
+        *fStatus = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    cn->fLeftChild = fTree;
+    fTree->fParent = cn;
+    cn->fRightChild = new RBBINode(RBBINode::endMark);
+    // Delete and exit if memory allocation failed.
+    if (cn->fRightChild == NULL) {
+        *fStatus = U_MEMORY_ALLOCATION_ERROR;
+        delete cn;
+        return;
+    }
+    cn->fRightChild->fParent = cn;
+    fTree = cn;
+
+    //
+    //  Replace all references to UnicodeSets with the tree for the equivalent
+    //      expression.
+    //
+    fTree->flattenSets();
+#ifdef RBBI_DEBUG
+    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "stree")) {
+        RBBIDebugPuts("Parse tree after flattening Unicode Set references.");
+        fTree->printTree(TRUE);
+    }
+#endif
+
+
+    //
+    // calculate the functions nullable, firstpos, lastpos and followpos on
+    // nodes in the parse tree.
+    //    See the alogrithm description in Aho.
+    //    Understanding how this works by looking at the code alone will be
+    //       nearly impossible.
+    //
+    calcNullable(fTree);
+    calcFirstPos(fTree);
+    calcLastPos(fTree);
+    calcFollowPos(fTree);
+    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "pos")) {
+        RBBIDebugPuts("\n");
+        printPosSets(fTree);
+    }
+
+    //
+    //  For "chained" rules, modify the followPos sets
+    //
+    if (fRB->fChainRules) {
+        calcChainedFollowPos(fTree);
+    }
+
+    //
+    //  BOF (start of input) test fixup.
+    //
+    if (fRB->fSetBuilder->sawBOF()) {
+        bofFixup();
+    }
+
+    //
+    // Build the DFA state transition tables.
+    //
+    buildStateTable();
+    flagAcceptingStates();
+    flagLookAheadStates();
+    flagTaggedStates();
+
+    //
+    // Update the global table of rule status {tag} values
+    // The rule builder has a global vector of status values that are common
+    //    for all tables.  Merge the ones from this table into the global set.
+    //
+    mergeRuleStatusVals();
+
+    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "states")) {printStates();};
+}
+
+
+
+//-----------------------------------------------------------------------------
+//
+//   calcNullable.    Impossible to explain succinctly.  See Aho, section 3.9
+//
+//-----------------------------------------------------------------------------
+void RBBITableBuilder::calcNullable(RBBINode *n) {
+    if (n == NULL) {
+        return;
+    }
+    if (n->fType == RBBINode::setRef ||
+        n->fType == RBBINode::endMark ) {
+        // These are non-empty leaf node types.
+        n->fNullable = FALSE;
+        return;
+    }
+
+    if (n->fType == RBBINode::lookAhead || n->fType == RBBINode::tag) {
+        // Lookahead marker node.  It's a leaf, so no recursion on children.
+        // It's nullable because it does not match any literal text from the input stream.
+        n->fNullable = TRUE;
+        return;
+    }
+
+
+    // The node is not a leaf.
+    //  Calculate nullable on its children.
+    calcNullable(n->fLeftChild);
+    calcNullable(n->fRightChild);
+
+    // Apply functions from table 3.40 in Aho
+    if (n->fType == RBBINode::opOr) {
+        n->fNullable = n->fLeftChild->fNullable || n->fRightChild->fNullable;
+    }
+    else if (n->fType == RBBINode::opCat) {
+        n->fNullable = n->fLeftChild->fNullable && n->fRightChild->fNullable;
+    }
+    else if (n->fType == RBBINode::opStar || n->fType == RBBINode::opQuestion) {
+        n->fNullable = TRUE;
+    }
+    else {
+        n->fNullable = FALSE;
+    }
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+//
+//   calcFirstPos.    Impossible to explain succinctly.  See Aho, section 3.9
+//
+//-----------------------------------------------------------------------------
+void RBBITableBuilder::calcFirstPos(RBBINode *n) {
+    if (n == NULL) {
+        return;
+    }
+    if (n->fType == RBBINode::leafChar  ||
+        n->fType == RBBINode::endMark   ||
+        n->fType == RBBINode::lookAhead ||
+        n->fType == RBBINode::tag) {
+        // These are non-empty leaf node types.
+        // Note: In order to maintain the sort invariant on the set,
+        // this function should only be called on a node whose set is
+        // empty to start with.
+        n->fFirstPosSet->addElement(n, *fStatus);
+        return;
+    }
+
+    // The node is not a leaf.
+    //  Calculate firstPos on its children.
+    calcFirstPos(n->fLeftChild);
+    calcFirstPos(n->fRightChild);
+
+    // Apply functions from table 3.40 in Aho
+    if (n->fType == RBBINode::opOr) {
+        setAdd(n->fFirstPosSet, n->fLeftChild->fFirstPosSet);
+        setAdd(n->fFirstPosSet, n->fRightChild->fFirstPosSet);
+    }
+    else if (n->fType == RBBINode::opCat) {
+        setAdd(n->fFirstPosSet, n->fLeftChild->fFirstPosSet);
+        if (n->fLeftChild->fNullable) {
+            setAdd(n->fFirstPosSet, n->fRightChild->fFirstPosSet);
+        }
+    }
+    else if (n->fType == RBBINode::opStar ||
+             n->fType == RBBINode::opQuestion ||
+             n->fType == RBBINode::opPlus) {
+        setAdd(n->fFirstPosSet, n->fLeftChild->fFirstPosSet);
+    }
+}
+
+
+
+//-----------------------------------------------------------------------------
+//
+//   calcLastPos.    Impossible to explain succinctly.  See Aho, section 3.9
+//
+//-----------------------------------------------------------------------------
+void RBBITableBuilder::calcLastPos(RBBINode *n) {
+    if (n == NULL) {
+        return;
+    }
+    if (n->fType == RBBINode::leafChar  ||
+        n->fType == RBBINode::endMark   ||
+        n->fType == RBBINode::lookAhead ||
+        n->fType == RBBINode::tag) {
+        // These are non-empty leaf node types.
+        // Note: In order to maintain the sort invariant on the set,
+        // this function should only be called on a node whose set is
+        // empty to start with.
+        n->fLastPosSet->addElement(n, *fStatus);
+        return;
+    }
+
+    // The node is not a leaf.
+    //  Calculate lastPos on its children.
+    calcLastPos(n->fLeftChild);
+    calcLastPos(n->fRightChild);
+
+    // Apply functions from table 3.40 in Aho
+    if (n->fType == RBBINode::opOr) {
+        setAdd(n->fLastPosSet, n->fLeftChild->fLastPosSet);
+        setAdd(n->fLastPosSet, n->fRightChild->fLastPosSet);
+    }
+    else if (n->fType == RBBINode::opCat) {
+        setAdd(n->fLastPosSet, n->fRightChild->fLastPosSet);
+        if (n->fRightChild->fNullable) {
+            setAdd(n->fLastPosSet, n->fLeftChild->fLastPosSet);
+        }
+    }
+    else if (n->fType == RBBINode::opStar     ||
+             n->fType == RBBINode::opQuestion ||
+             n->fType == RBBINode::opPlus) {
+        setAdd(n->fLastPosSet, n->fLeftChild->fLastPosSet);
+    }
+}
+
+
+
+//-----------------------------------------------------------------------------
+//
+//   calcFollowPos.    Impossible to explain succinctly.  See Aho, section 3.9
+//
+//-----------------------------------------------------------------------------
+void RBBITableBuilder::calcFollowPos(RBBINode *n) {
+    if (n == NULL ||
+        n->fType == RBBINode::leafChar ||
+        n->fType == RBBINode::endMark) {
+        return;
+    }
+
+    calcFollowPos(n->fLeftChild);
+    calcFollowPos(n->fRightChild);
+
+    // Aho rule #1
+    if (n->fType == RBBINode::opCat) {
+        RBBINode *i;   // is 'i' in Aho's description
+        uint32_t     ix;
+
+        UVector *LastPosOfLeftChild = n->fLeftChild->fLastPosSet;
+
+        for (ix=0; ix<(uint32_t)LastPosOfLeftChild->size(); ix++) {
+            i = (RBBINode *)LastPosOfLeftChild->elementAt(ix);
+            setAdd(i->fFollowPos, n->fRightChild->fFirstPosSet);
+        }
+    }
+
+    // Aho rule #2
+    if (n->fType == RBBINode::opStar ||
+        n->fType == RBBINode::opPlus) {
+        RBBINode   *i;  // again, n and i are the names from Aho's description.
+        uint32_t    ix;
+
+        for (ix=0; ix<(uint32_t)n->fLastPosSet->size(); ix++) {
+            i = (RBBINode *)n->fLastPosSet->elementAt(ix);
+            setAdd(i->fFollowPos, n->fFirstPosSet);
+        }
+    }
+
+
+
+}
+
+
+//-----------------------------------------------------------------------------
+//
+//   calcChainedFollowPos.    Modify the previously calculated followPos sets
+//                            to implement rule chaining.  NOT described by Aho
+//
+//-----------------------------------------------------------------------------
+void RBBITableBuilder::calcChainedFollowPos(RBBINode *tree) {
+
+    UVector         endMarkerNodes(*fStatus);
+    UVector         leafNodes(*fStatus);
+    int32_t         i;
+
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+
+    // get a list of all endmarker nodes.
+    tree->findNodes(&endMarkerNodes, RBBINode::endMark, *fStatus);
+
+    // get a list all leaf nodes
+    tree->findNodes(&leafNodes, RBBINode::leafChar, *fStatus);
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+
+    // Get all nodes that can be the start a match, which is FirstPosition()
+    // of the portion of the tree corresponding to user-written rules.
+    // See the tree description in bofFixup().
+    RBBINode *userRuleRoot = tree;
+    if (fRB->fSetBuilder->sawBOF()) {
+        userRuleRoot = tree->fLeftChild->fRightChild;
+    }
+    U_ASSERT(userRuleRoot != NULL);
+    UVector *matchStartNodes = userRuleRoot->fFirstPosSet;
+
+
+    // Iteratate over all leaf nodes,
+    //
+    int32_t  endNodeIx;
+    int32_t  startNodeIx;
+
+    for (endNodeIx=0; endNodeIx<leafNodes.size(); endNodeIx++) {
+        RBBINode *tNode   = (RBBINode *)leafNodes.elementAt(endNodeIx);
+        RBBINode *endNode = NULL;
+
+        // Identify leaf nodes that correspond to overall rule match positions.
+        //   These include an endMarkerNode in their followPos sets.
+        for (i=0; i<endMarkerNodes.size(); i++) {
+            if (tNode->fFollowPos->contains(endMarkerNodes.elementAt(i))) {
+                endNode = tNode;
+                break;
+            }
+        }
+        if (endNode == NULL) {
+            // node wasn't an end node.  Try again with the next.
+            continue;
+        }
+
+        // We've got a node that can end a match.
+
+        // Line Break Specific hack:  If this node's val correspond to the $CM char class,
+        //                            don't chain from it.
+        // TODO:  Add rule syntax for this behavior, get specifics out of here and
+        //        into the rule file.
+        if (fRB->fLBCMNoChain) {
+            UChar32 c = this->fRB->fSetBuilder->getFirstChar(endNode->fVal);
+            if (c != -1) {
+                // c == -1 occurs with sets containing only the {eof} marker string.
+                ULineBreak cLBProp = (ULineBreak)u_getIntPropertyValue(c, UCHAR_LINE_BREAK);
+                if (cLBProp == U_LB_COMBINING_MARK) {
+                    continue;
+                }
+            }
+        }
+
+
+        // Now iterate over the nodes that can start a match, looking for ones
+        //   with the same char class as our ending node.
+        RBBINode *startNode;
+        for (startNodeIx = 0; startNodeIx<matchStartNodes->size(); startNodeIx++) {
+            startNode = (RBBINode *)matchStartNodes->elementAt(startNodeIx);
+            if (startNode->fType != RBBINode::leafChar) {
+                continue;
+            }
+
+            if (endNode->fVal == startNode->fVal) {
+                // The end val (character class) of one possible match is the
+                //   same as the start of another.
+
+                // Add all nodes from the followPos of the start node to the
+                //  followPos set of the end node, which will have the effect of
+                //  letting matches transition from a match state at endNode
+                //  to the second char of a match starting with startNode.
+                setAdd(endNode->fFollowPos, startNode->fFollowPos);
+            }
+        }
+    }
+}
+
+
+//-----------------------------------------------------------------------------
+//
+//   bofFixup.    Fixup for state tables that include {bof} beginning of input testing.
+//                Do an swizzle similar to chaining, modifying the followPos set of
+//                the bofNode to include the followPos nodes from other {bot} nodes
+//                scattered through the tree.
+//
+//                This function has much in common with calcChainedFollowPos().
+//
+//-----------------------------------------------------------------------------
+void RBBITableBuilder::bofFixup() {
+
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+
+    //   The parse tree looks like this ...
+    //         fTree root  --->       <cat>
+    //                               /     \       .
+    //                            <cat>   <#end node>
+    //                           /     \  .
+    //                     <bofNode>   rest
+    //                               of tree
+    //
+    //    We will be adding things to the followPos set of the <bofNode>
+    //
+    RBBINode  *bofNode = fTree->fLeftChild->fLeftChild;
+    U_ASSERT(bofNode->fType == RBBINode::leafChar);
+    U_ASSERT(bofNode->fVal == 2);
+
+    // Get all nodes that can be the start a match of the user-written rules
+    //  (excluding the fake bofNode)
+    //  We want the nodes that can start a match in the
+    //     part labeled "rest of tree"
+    // 
+    UVector *matchStartNodes = fTree->fLeftChild->fRightChild->fFirstPosSet;
+
+    RBBINode *startNode;
+    int       startNodeIx;
+    for (startNodeIx = 0; startNodeIx<matchStartNodes->size(); startNodeIx++) {
+        startNode = (RBBINode *)matchStartNodes->elementAt(startNodeIx);
+        if (startNode->fType != RBBINode::leafChar) {
+            continue;
+        }
+
+        if (startNode->fVal == bofNode->fVal) {
+            //  We found a leaf node corresponding to a {bof} that was
+            //    explicitly written into a rule.
+            //  Add everything from the followPos set of this node to the
+            //    followPos set of the fake bofNode at the start of the tree.
+            //  
+            setAdd(bofNode->fFollowPos, startNode->fFollowPos);
+        }
+    }
+}
+
+//-----------------------------------------------------------------------------
+//
+//   buildStateTable()    Determine the set of runtime DFA states and the
+//                        transition tables for these states, by the algorithm
+//                        of fig. 3.44 in Aho.
+//
+//                        Most of the comments are quotes of Aho's psuedo-code.
+//
+//-----------------------------------------------------------------------------
+void RBBITableBuilder::buildStateTable() {
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+    RBBIStateDescriptor *failState;
+    // Set it to NULL to avoid uninitialized warning
+    RBBIStateDescriptor *initialState = NULL; 
+    //
+    // Add a dummy state 0 - the stop state.  Not from Aho.
+    int      lastInputSymbol = fRB->fSetBuilder->getNumCharCategories() - 1;
+    failState = new RBBIStateDescriptor(lastInputSymbol, fStatus);
+    if (failState == NULL) {
+        *fStatus = U_MEMORY_ALLOCATION_ERROR;
+        goto ExitBuildSTdeleteall;
+    }
+    failState->fPositions = new UVector(*fStatus);
+    if (failState->fPositions == NULL) {
+        *fStatus = U_MEMORY_ALLOCATION_ERROR;
+    }
+    if (failState->fPositions == NULL || U_FAILURE(*fStatus)) {
+        goto ExitBuildSTdeleteall;
+    }
+    fDStates->addElement(failState, *fStatus);
+    if (U_FAILURE(*fStatus)) {
+        goto ExitBuildSTdeleteall;
+    }
+
+    // initially, the only unmarked state in Dstates is firstpos(root),
+    //       where toot is the root of the syntax tree for (r)#;
+    initialState = new RBBIStateDescriptor(lastInputSymbol, fStatus);
+    if (initialState == NULL) {
+        *fStatus = U_MEMORY_ALLOCATION_ERROR;
+    }
+    if (U_FAILURE(*fStatus)) {
+        goto ExitBuildSTdeleteall;
+    }
+    initialState->fPositions = new UVector(*fStatus);
+    if (initialState->fPositions == NULL) {
+        *fStatus = U_MEMORY_ALLOCATION_ERROR;
+    }
+    if (U_FAILURE(*fStatus)) {
+        goto ExitBuildSTdeleteall;
+    }
+    setAdd(initialState->fPositions, fTree->fFirstPosSet);
+    fDStates->addElement(initialState, *fStatus);
+    if (U_FAILURE(*fStatus)) {
+        goto ExitBuildSTdeleteall;
+    }
+
+    // while there is an unmarked state T in Dstates do begin
+    for (;;) {
+        RBBIStateDescriptor *T = NULL;
+        int32_t              tx;
+        for (tx=1; tx<fDStates->size(); tx++) {
+            RBBIStateDescriptor *temp;
+            temp = (RBBIStateDescriptor *)fDStates->elementAt(tx);
+            if (temp->fMarked == FALSE) {
+                T = temp;
+                break;
+            }
+        }
+        if (T == NULL) {
+            break;
+        }
+
+        // mark T;
+        T->fMarked = TRUE;
+
+        // for each input symbol a do begin
+        int32_t  a;
+        for (a = 1; a<=lastInputSymbol; a++) {
+            // let U be the set of positions that are in followpos(p)
+            //    for some position p in T
+            //    such that the symbol at position p is a;
+            UVector    *U = NULL;
+            RBBINode   *p;
+            int32_t     px;
+            for (px=0; px<T->fPositions->size(); px++) {
+                p = (RBBINode *)T->fPositions->elementAt(px);
+                if ((p->fType == RBBINode::leafChar) &&  (p->fVal == a)) {
+                    if (U == NULL) {
+                        U = new UVector(*fStatus);
+                        if (U == NULL) {
+                        	*fStatus = U_MEMORY_ALLOCATION_ERROR;
+                        	goto ExitBuildSTdeleteall;
+                        }
+                    }
+                    setAdd(U, p->fFollowPos);
+                }
+            }
+
+            // if U is not empty and not in DStates then
+            int32_t  ux = 0;
+            UBool    UinDstates = FALSE;
+            if (U != NULL) {
+                U_ASSERT(U->size() > 0);
+                int  ix;
+                for (ix=0; ix<fDStates->size(); ix++) {
+                    RBBIStateDescriptor *temp2;
+                    temp2 = (RBBIStateDescriptor *)fDStates->elementAt(ix);
+                    if (setEquals(U, temp2->fPositions)) {
+                        delete U;
+                        U  = temp2->fPositions;
+                        ux = ix;
+                        UinDstates = TRUE;
+                        break;
+                    }
+                }
+
+                // Add U as an unmarked state to Dstates
+                if (!UinDstates)
+                {
+                    RBBIStateDescriptor *newState = new RBBIStateDescriptor(lastInputSymbol, fStatus);
+                    if (newState == NULL) {
+                    	*fStatus = U_MEMORY_ALLOCATION_ERROR;
+                    }
+                    if (U_FAILURE(*fStatus)) {
+                        goto ExitBuildSTdeleteall;
+                    }
+                    newState->fPositions = U;
+                    fDStates->addElement(newState, *fStatus);
+                    if (U_FAILURE(*fStatus)) {
+                        return;
+                    }
+                    ux = fDStates->size()-1;
+                }
+
+                // Dtran[T, a] := U;
+                T->fDtran->setElementAt(ux, a);
+            }
+        }
+    }
+    return;
+    // delete local pointers only if error occured.
+ExitBuildSTdeleteall:
+    delete initialState;
+    delete failState;
+}
+
+
+
+//-----------------------------------------------------------------------------
+//
+//   flagAcceptingStates    Identify accepting states.
+//                          First get a list of all of the end marker nodes.
+//                          Then, for each state s,
+//                              if s contains one of the end marker nodes in its list of tree positions then
+//                                  s is an accepting state.
+//
+//-----------------------------------------------------------------------------
+void     RBBITableBuilder::flagAcceptingStates() {
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+    UVector     endMarkerNodes(*fStatus);
+    RBBINode    *endMarker;
+    int32_t     i;
+    int32_t     n;
+
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+
+    fTree->findNodes(&endMarkerNodes, RBBINode::endMark, *fStatus);
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+
+    for (i=0; i<endMarkerNodes.size(); i++) {
+        endMarker = (RBBINode *)endMarkerNodes.elementAt(i);
+        for (n=0; n<fDStates->size(); n++) {
+            RBBIStateDescriptor *sd = (RBBIStateDescriptor *)fDStates->elementAt(n);
+            if (sd->fPositions->indexOf(endMarker) >= 0) {
+                // Any non-zero value for fAccepting means this is an accepting node.
+                // The value is what will be returned to the user as the break status.
+                // If no other value was specified, force it to -1.
+
+                if (sd->fAccepting==0) {
+                    // State hasn't been marked as accepting yet.  Do it now.
+                    sd->fAccepting = endMarker->fVal;
+                    if (sd->fAccepting == 0) {
+                        sd->fAccepting = -1;
+                    }
+                }
+                if (sd->fAccepting==-1 && endMarker->fVal != 0) {
+                    // Both lookahead and non-lookahead accepting for this state.
+                    // Favor the look-ahead.  Expedient for line break.
+                    // TODO:  need a more elegant resolution for conflicting rules.
+                    sd->fAccepting = endMarker->fVal;
+                }
+                // implicit else:
+                // if sd->fAccepting already had a value other than 0 or -1, leave it be.
+
+                // If the end marker node is from a look-ahead rule, set
+                //   the fLookAhead field or this state also.
+                if (endMarker->fLookAheadEnd) {
+                    // TODO:  don't change value if already set?
+                    // TODO:  allow for more than one active look-ahead rule in engine.
+                    //        Make value here an index to a side array in engine?
+                    sd->fLookAhead = sd->fAccepting;
+                }
+            }
+        }
+    }
+}
+
+
+//-----------------------------------------------------------------------------
+//
+//    flagLookAheadStates   Very similar to flagAcceptingStates, above.
+//
+//-----------------------------------------------------------------------------
+void     RBBITableBuilder::flagLookAheadStates() {
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+    UVector     lookAheadNodes(*fStatus);
+    RBBINode    *lookAheadNode;
+    int32_t     i;
+    int32_t     n;
+
+    fTree->findNodes(&lookAheadNodes, RBBINode::lookAhead, *fStatus);
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+    for (i=0; i<lookAheadNodes.size(); i++) {
+        lookAheadNode = (RBBINode *)lookAheadNodes.elementAt(i);
+
+        for (n=0; n<fDStates->size(); n++) {
+            RBBIStateDescriptor *sd = (RBBIStateDescriptor *)fDStates->elementAt(n);
+            if (sd->fPositions->indexOf(lookAheadNode) >= 0) {
+                sd->fLookAhead = lookAheadNode->fVal;
+            }
+        }
+    }
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+//
+//    flagTaggedStates
+//
+//-----------------------------------------------------------------------------
+void     RBBITableBuilder::flagTaggedStates() {
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+    UVector     tagNodes(*fStatus);
+    RBBINode    *tagNode;
+    int32_t     i;
+    int32_t     n;
+
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+    fTree->findNodes(&tagNodes, RBBINode::tag, *fStatus);
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+    for (i=0; i<tagNodes.size(); i++) {                   // For each tag node t (all of 'em)
+        tagNode = (RBBINode *)tagNodes.elementAt(i);
+
+        for (n=0; n<fDStates->size(); n++) {              //    For each state  s (row in the state table)
+            RBBIStateDescriptor *sd = (RBBIStateDescriptor *)fDStates->elementAt(n);
+            if (sd->fPositions->indexOf(tagNode) >= 0) {  //       if  s include the tag node t
+                sortedAdd(&sd->fTagVals, tagNode->fVal);
+            }
+        }
+    }
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+//
+//  mergeRuleStatusVals
+//
+//      Update the global table of rule status {tag} values
+//      The rule builder has a global vector of status values that are common
+//      for all tables.  Merge the ones from this table into the global set.
+//
+//-----------------------------------------------------------------------------
+void  RBBITableBuilder::mergeRuleStatusVals() {
+    //
+    //  The basic outline of what happens here is this...
+    //
+    //    for each state in this state table
+    //       if the status tag list for this state is in the global statuses list
+    //           record where and
+    //           continue with the next state
+    //       else
+    //           add the tag list for this state to the global list.
+    //
+    int i;
+    int n;
+
+    // Pre-set a single tag of {0} into the table.
+    //   We will need this as a default, for rule sets with no explicit tagging.
+    if (fRB->fRuleStatusVals->size() == 0) {
+        fRB->fRuleStatusVals->addElement(1, *fStatus);  // Num of statuses in group
+        fRB->fRuleStatusVals->addElement((int32_t)0, *fStatus);  //   and our single status of zero
+    }
+
+    //    For each state
+    for (n=0; n<fDStates->size(); n++) {
+        RBBIStateDescriptor *sd = (RBBIStateDescriptor *)fDStates->elementAt(n);
+        UVector *thisStatesTagValues = sd->fTagVals;
+        if (thisStatesTagValues == NULL) {
+            // No tag values are explicitly associated with this state.
+            //   Set the default tag value.
+            sd->fTagsIdx = 0;
+            continue;
+        }
+
+        // There are tag(s) associated with this state.
+        //   fTagsIdx will be the index into the global tag list for this state's tag values.
+        //   Initial value of -1 flags that we haven't got it set yet.
+        sd->fTagsIdx = -1;
+        int32_t  thisTagGroupStart = 0;   // indexes into the global rule status vals list
+        int32_t  nextTagGroupStart = 0;
+
+        // Loop runs once per group of tags in the global list
+        while (nextTagGroupStart < fRB->fRuleStatusVals->size()) {
+            thisTagGroupStart = nextTagGroupStart;
+            nextTagGroupStart += fRB->fRuleStatusVals->elementAti(thisTagGroupStart) + 1;
+            if (thisStatesTagValues->size() != fRB->fRuleStatusVals->elementAti(thisTagGroupStart)) {
+                // The number of tags for this state is different from
+                //    the number of tags in this group from the global list.
+                //    Continue with the next group from the global list.
+                continue;
+            }
+            // The lengths match, go ahead and compare the actual tag values
+            //    between this state and the group from the global list.
+            for (i=0; i<thisStatesTagValues->size(); i++) {
+                if (thisStatesTagValues->elementAti(i) !=
+                    fRB->fRuleStatusVals->elementAti(thisTagGroupStart + 1 + i) ) {
+                    // Mismatch.
+                    break;
+                }
+            }
+
+            if (i == thisStatesTagValues->size()) {
+                // We found a set of tag values in the global list that match
+                //   those for this state.  Use them.
+                sd->fTagsIdx = thisTagGroupStart;
+                break;
+            }
+        }
+
+        if (sd->fTagsIdx == -1) {
+            // No suitable entry in the global tag list already.  Add one
+            sd->fTagsIdx = fRB->fRuleStatusVals->size();
+            fRB->fRuleStatusVals->addElement(thisStatesTagValues->size(), *fStatus);
+            for (i=0; i<thisStatesTagValues->size(); i++) {
+                fRB->fRuleStatusVals->addElement(thisStatesTagValues->elementAti(i), *fStatus);
+            }
+        }
+    }
+}
+
+
+
+
+
+
+
+//-----------------------------------------------------------------------------
+//
+//  sortedAdd  Add a value to a vector of sorted values (ints).
+//             Do not replicate entries; if the value is already there, do not
+//                add a second one.
+//             Lazily create the vector if it does not already exist.
+//
+//-----------------------------------------------------------------------------
+void RBBITableBuilder::sortedAdd(UVector **vector, int32_t val) {
+    int32_t i;
+
+    if (*vector == NULL) {
+        *vector = new UVector(*fStatus);
+    }
+    if (*vector == NULL || U_FAILURE(*fStatus)) {
+        return;
+    }
+    UVector *vec = *vector;
+    int32_t  vSize = vec->size();
+    for (i=0; i<vSize; i++) {
+        int32_t valAtI = vec->elementAti(i);
+        if (valAtI == val) {
+            // The value is already in the vector.  Don't add it again.
+            return;
+        }
+        if (valAtI > val) {
+            break;
+        }
+    }
+    vec->insertElementAt(val, i, *fStatus);
+}
+
+
+
+//-----------------------------------------------------------------------------
+//
+//  setAdd     Set operation on UVector
+//             dest = dest union source
+//             Elements may only appear once and must be sorted.
+//
+//-----------------------------------------------------------------------------
+void RBBITableBuilder::setAdd(UVector *dest, UVector *source) {
+    int32_t destOriginalSize = dest->size();
+    int32_t sourceSize       = source->size();
+    int32_t di           = 0;
+    MaybeStackArray<void *, 16> destArray, sourceArray;  // Handle small cases without malloc
+    void **destPtr, **sourcePtr;
+    void **destLim, **sourceLim;
+
+    if (destOriginalSize > destArray.getCapacity()) {
+        if (destArray.resize(destOriginalSize) == NULL) {
+            return;
+        }
+    }
+    destPtr = destArray.getAlias();
+    destLim = destPtr + destOriginalSize;  // destArray.getArrayLimit()?
+
+    if (sourceSize > sourceArray.getCapacity()) {
+        if (sourceArray.resize(sourceSize) == NULL) {
+            return;
+        }
+    }
+    sourcePtr = sourceArray.getAlias();
+    sourceLim = sourcePtr + sourceSize;  // sourceArray.getArrayLimit()?
+
+    // Avoid multiple "get element" calls by getting the contents into arrays
+    (void) dest->toArray(destPtr);
+    (void) source->toArray(sourcePtr);
+
+    dest->setSize(sourceSize+destOriginalSize, *fStatus);
+
+    while (sourcePtr < sourceLim && destPtr < destLim) {
+        if (*destPtr == *sourcePtr) {
+            dest->setElementAt(*sourcePtr++, di++);
+            destPtr++;
+        }
+        // This check is required for machines with segmented memory, like i5/OS.
+        // Direct pointer comparison is not recommended.
+        else if (uprv_memcmp(destPtr, sourcePtr, sizeof(void *)) < 0) {
+            dest->setElementAt(*destPtr++, di++);
+        }
+        else { /* *sourcePtr < *destPtr */
+            dest->setElementAt(*sourcePtr++, di++);
+        }
+    }
+
+    // At most one of these two cleanup loops will execute
+    while (destPtr < destLim) {
+        dest->setElementAt(*destPtr++, di++);
+    }
+    while (sourcePtr < sourceLim) {
+        dest->setElementAt(*sourcePtr++, di++);
+    }
+
+    dest->setSize(di, *fStatus);
+}
+
+
+
+//-----------------------------------------------------------------------------
+//
+//  setEqual    Set operation on UVector.
+//              Compare for equality.
+//              Elements must be sorted.
+//
+//-----------------------------------------------------------------------------
+UBool RBBITableBuilder::setEquals(UVector *a, UVector *b) {
+    return a->equals(*b);
+}
+
+
+//-----------------------------------------------------------------------------
+//
+//  printPosSets   Debug function.  Dump Nullable, firstpos, lastpos and followpos
+//                 for each node in the tree.
+//
+//-----------------------------------------------------------------------------
+#ifdef RBBI_DEBUG
+void RBBITableBuilder::printPosSets(RBBINode *n) {
+    if (n==NULL) {
+        return;
+    }
+    n->printNode();
+    RBBIDebugPrintf("         Nullable:  %s\n", n->fNullable?"TRUE":"FALSE");
+
+    RBBIDebugPrintf("         firstpos:  ");
+    printSet(n->fFirstPosSet);
+
+    RBBIDebugPrintf("         lastpos:   ");
+    printSet(n->fLastPosSet);
+
+    RBBIDebugPrintf("         followpos: ");
+    printSet(n->fFollowPos);
+
+    printPosSets(n->fLeftChild);
+    printPosSets(n->fRightChild);
+}
+#endif
+
+
+
+//-----------------------------------------------------------------------------
+//
+//   getTableSize()    Calculate the size of the runtime form of this
+//                     state transition table.
+//
+//-----------------------------------------------------------------------------
+int32_t  RBBITableBuilder::getTableSize() const {
+    int32_t    size = 0;
+    int32_t    numRows;
+    int32_t    numCols;
+    int32_t    rowSize;
+
+    if (fTree == NULL) {
+        return 0;
+    }
+
+    size    = sizeof(RBBIStateTable) - 4;    // The header, with no rows to the table.
+
+    numRows = fDStates->size();
+    numCols = fRB->fSetBuilder->getNumCharCategories();
+
+    //  Note  The declaration of RBBIStateTableRow is for a table of two columns.
+    //        Therefore we subtract two from numCols when determining
+    //        how much storage to add to a row for the total columns.
+    rowSize = sizeof(RBBIStateTableRow) + sizeof(uint16_t)*(numCols-2);
+    size   += numRows * rowSize;
+    return size;
+}
+
+
+
+//-----------------------------------------------------------------------------
+//
+//   exportTable()    export the state transition table in the format required
+//                    by the runtime engine.  getTableSize() bytes of memory
+//                    must be available at the output address "where".
+//
+//-----------------------------------------------------------------------------
+void RBBITableBuilder::exportTable(void *where) {
+    RBBIStateTable    *table = (RBBIStateTable *)where;
+    uint32_t           state;
+    int                col;
+
+    if (U_FAILURE(*fStatus) || fTree == NULL) {
+        return;
+    }
+
+    if (fRB->fSetBuilder->getNumCharCategories() > 0x7fff ||
+        fDStates->size() > 0x7fff) {
+        *fStatus = U_BRK_INTERNAL_ERROR;
+        return;
+    }
+
+    table->fRowLen    = sizeof(RBBIStateTableRow) +
+                            sizeof(uint16_t) * (fRB->fSetBuilder->getNumCharCategories() - 2);
+    table->fNumStates = fDStates->size();
+    table->fFlags     = 0;
+    if (fRB->fLookAheadHardBreak) {
+        table->fFlags  |= RBBI_LOOKAHEAD_HARD_BREAK;
+    }
+    if (fRB->fSetBuilder->sawBOF()) {
+        table->fFlags  |= RBBI_BOF_REQUIRED;
+    }
+    table->fReserved  = 0;
+
+    for (state=0; state<table->fNumStates; state++) {
+        RBBIStateDescriptor *sd = (RBBIStateDescriptor *)fDStates->elementAt(state);
+        RBBIStateTableRow   *row = (RBBIStateTableRow *)(table->fTableData + state*table->fRowLen);
+        U_ASSERT (-32768 < sd->fAccepting && sd->fAccepting <= 32767);
+        U_ASSERT (-32768 < sd->fLookAhead && sd->fLookAhead <= 32767);
+        row->fAccepting = (int16_t)sd->fAccepting;
+        row->fLookAhead = (int16_t)sd->fLookAhead;
+        row->fTagIdx    = (int16_t)sd->fTagsIdx;
+        for (col=0; col<fRB->fSetBuilder->getNumCharCategories(); col++) {
+            row->fNextState[col] = (uint16_t)sd->fDtran->elementAti(col);
+        }
+    }
+}
+
+
+
+//-----------------------------------------------------------------------------
+//
+//   printSet    Debug function.   Print the contents of a UVector
+//
+//-----------------------------------------------------------------------------
+#ifdef RBBI_DEBUG
+void RBBITableBuilder::printSet(UVector *s) {
+    int32_t  i;
+    for (i=0; i<s->size(); i++) {
+        void *v = s->elementAt(i);
+        RBBIDebugPrintf("%10p", v);
+    }
+    RBBIDebugPrintf("\n");
+}
+#endif
+
+
+//-----------------------------------------------------------------------------
+//
+//   printStates    Debug Function.  Dump the fully constructed state transition table.
+//
+//-----------------------------------------------------------------------------
+#ifdef RBBI_DEBUG
+void RBBITableBuilder::printStates() {
+    int     c;    // input "character"
+    int     n;    // state number
+
+    RBBIDebugPrintf("state |           i n p u t     s y m b o l s \n");
+    RBBIDebugPrintf("      | Acc  LA    Tag");
+    for (c=0; c<fRB->fSetBuilder->getNumCharCategories(); c++) {
+        RBBIDebugPrintf(" %2d", c);
+    }
+    RBBIDebugPrintf("\n");
+    RBBIDebugPrintf("      |---------------");
+    for (c=0; c<fRB->fSetBuilder->getNumCharCategories(); c++) {
+        RBBIDebugPrintf("---");
+    }
+    RBBIDebugPrintf("\n");
+
+    for (n=0; n<fDStates->size(); n++) {
+        RBBIStateDescriptor *sd = (RBBIStateDescriptor *)fDStates->elementAt(n);
+        RBBIDebugPrintf("  %3d | " , n);
+        RBBIDebugPrintf("%3d %3d %5d ", sd->fAccepting, sd->fLookAhead, sd->fTagsIdx);
+        for (c=0; c<fRB->fSetBuilder->getNumCharCategories(); c++) {
+            RBBIDebugPrintf(" %2d", sd->fDtran->elementAti(c));
+        }
+        RBBIDebugPrintf("\n");
+    }
+    RBBIDebugPrintf("\n\n");
+}
+#endif
+
+
+
+//-----------------------------------------------------------------------------
+//
+//   printRuleStatusTable    Debug Function.  Dump the common rule status table
+//
+//-----------------------------------------------------------------------------
+#ifdef RBBI_DEBUG
+void RBBITableBuilder::printRuleStatusTable() {
+    int32_t  thisRecord = 0;
+    int32_t  nextRecord = 0;
+    int      i;
+    UVector  *tbl = fRB->fRuleStatusVals;
+
+    RBBIDebugPrintf("index |  tags \n");
+    RBBIDebugPrintf("-------------------\n");
+
+    while (nextRecord < tbl->size()) {
+        thisRecord = nextRecord;
+        nextRecord = thisRecord + tbl->elementAti(thisRecord) + 1;
+        RBBIDebugPrintf("%4d   ", thisRecord);
+        for (i=thisRecord+1; i<nextRecord; i++) {
+            RBBIDebugPrintf("  %5d", tbl->elementAti(i));
+        }
+        RBBIDebugPrintf("\n");
+    }
+    RBBIDebugPrintf("\n\n");
+}
+#endif
+
+
+//-----------------------------------------------------------------------------
+//
+//   RBBIStateDescriptor     Methods.  This is a very struct-like class
+//                           Most access is directly to the fields.
+//
+//-----------------------------------------------------------------------------
+
+RBBIStateDescriptor::RBBIStateDescriptor(int lastInputSymbol, UErrorCode *fStatus) {
+    fMarked    = FALSE;
+    fAccepting = 0;
+    fLookAhead = 0;
+    fTagsIdx   = 0;
+    fTagVals   = NULL;
+    fPositions = NULL;
+    fDtran     = NULL;
+
+    fDtran     = new UVector(lastInputSymbol+1, *fStatus);
+    if (U_FAILURE(*fStatus)) {
+        return;
+    }
+    if (fDtran == NULL) {
+        *fStatus = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    fDtran->setSize(lastInputSymbol+1, *fStatus);    // fDtran needs to be pre-sized.
+                                           //   It is indexed by input symbols, and will
+                                           //   hold  the next state number for each
+                                           //   symbol.
+}
+
+
+RBBIStateDescriptor::~RBBIStateDescriptor() {
+    delete       fPositions;
+    delete       fDtran;
+    delete       fTagVals;
+    fPositions = NULL;
+    fDtran     = NULL;
+    fTagVals   = NULL;
+}
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/icu/source/common/rbbitblb.h b/icu/source/common/rbbitblb.h
new file mode 100644
index 0000000..3805b67
--- /dev/null
+++ b/icu/source/common/rbbitblb.h
@@ -0,0 +1,127 @@
+//
+//  rbbitblb.h
+//
+
+/*
+**********************************************************************
+*   Copyright (c) 2002-2005, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*/
+
+#ifndef RBBITBLB_H
+#define RBBITBLB_H
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+#include "unicode/rbbi.h"
+#include "rbbinode.h"
+
+
+U_NAMESPACE_BEGIN
+
+class RBBIRuleScanner;
+class RBBIRuleBuilder;
+
+//
+//  class RBBITableBuilder is part of the RBBI rule compiler.
+//                         It builds the state transition table used by the RBBI runtime
+//                         from the expression syntax tree generated by the rule scanner.
+//
+//                         This class is part of the RBBI implementation only.
+//                         There is no user-visible public API here.
+//
+
+class RBBITableBuilder : public UMemory {
+public:
+    RBBITableBuilder(RBBIRuleBuilder *rb, RBBINode **rootNode);
+    ~RBBITableBuilder();
+
+    void     build();
+    int32_t  getTableSize() const;      // Return the runtime size in bytes of
+                                        //     the built state table
+    void     exportTable(void *where);  // fill in the runtime state table.
+                                        //     Sufficient memory must exist at
+                                        //     the specified location.
+
+
+private:
+    void     calcNullable(RBBINode *n);
+    void     calcFirstPos(RBBINode *n);
+    void     calcLastPos(RBBINode  *n);
+    void     calcFollowPos(RBBINode *n);
+    void     calcChainedFollowPos(RBBINode *n);
+    void     bofFixup();
+    void     buildStateTable();
+    void     flagAcceptingStates();
+    void     flagLookAheadStates();
+    void     flagTaggedStates();
+    void     mergeRuleStatusVals();
+
+    // Set functions for UVector.
+    //   TODO:  make a USet subclass of UVector
+
+    void     setAdd(UVector *dest, UVector *source);
+    UBool    setEquals(UVector *a, UVector *b);
+
+    void     sortedAdd(UVector **dest, int32_t val);
+
+public:
+#ifdef RBBI_DEBUG
+    void     printSet(UVector *s);
+    void     printPosSets(RBBINode *n /* = NULL*/);
+    void     printStates();
+    void     printRuleStatusTable();
+#else
+    #define  printSet(s)
+    #define  printPosSets(n)
+    #define  printStates()
+    #define  printRuleStatusTable()
+#endif
+
+private:
+    RBBIRuleBuilder  *fRB;
+    RBBINode         *&fTree;              // The root node of the parse tree to build a
+                                           //   table for.
+    UErrorCode       *fStatus;
+
+    UVector          *fDStates;            //  D states (Aho's terminology)
+                                           //  Index is state number
+                                           //  Contents are RBBIStateDescriptor pointers.
+
+
+    RBBITableBuilder(const RBBITableBuilder &other); // forbid copying of this class
+    RBBITableBuilder &operator=(const RBBITableBuilder &other); // forbid copying of this class
+};
+
+//
+//  RBBIStateDescriptor - The DFA is constructed as a set of these descriptors,
+//                        one for each state.
+class RBBIStateDescriptor : public UMemory {
+public:
+    UBool            fMarked;
+    int32_t          fAccepting;
+    int32_t          fLookAhead;
+    UVector          *fTagVals;
+    int32_t          fTagsIdx;
+    UVector          *fPositions;          // Set of parse tree positions associated
+                                           //   with this state.  Unordered (it's a set).
+                                           //   UVector contents are RBBINode *
+
+    UVector          *fDtran;              // Transitions out of this state.
+                                           //   indexed by input character
+                                           //   contents is int index of dest state
+                                           //   in RBBITableBuilder.fDStates
+
+    RBBIStateDescriptor(int maxInputSymbol,  UErrorCode *fStatus);
+    ~RBBIStateDescriptor();
+
+private:
+    RBBIStateDescriptor(const RBBIStateDescriptor &other); // forbid copying of this class
+    RBBIStateDescriptor &operator=(const RBBIStateDescriptor &other); // forbid copying of this class
+};
+
+
+
+U_NAMESPACE_END
+#endif
diff --git a/icu/source/common/resbund.cpp b/icu/source/common/resbund.cpp
new file mode 100644
index 0000000..082c5ab
--- /dev/null
+++ b/icu/source/common/resbund.cpp
@@ -0,0 +1,400 @@
+/*
+**********************************************************************
+*   Copyright (C) 1997-2008, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*
+* File resbund.cpp
+*
+* Modification History:
+*
+*   Date        Name        Description
+*   02/05/97    aliu        Fixed bug in chopLocale.  Added scanForLocaleInFile
+*                           based on code taken from scanForLocale.  Added
+*                           constructor which attempts to read resource bundle
+*                           from a specific file, without searching other files.
+*   02/11/97    aliu        Added UErrorCode return values to constructors. Fixed
+*                           infinite loops in scanForFile and scanForLocale.
+*                           Modified getRawResourceData to not delete storage in
+*                           localeData and resourceData which it doesn't own.
+*                           Added Mac compatibility #ifdefs for tellp() and
+*                           ios::nocreate.
+*   03/04/97    aliu        Modified to use ExpandingDataSink objects instead of
+*                           the highly inefficient ostrstream objects.
+*   03/13/97    aliu        Rewrote to load in entire resource bundle and store
+*                           it as a Hashtable of ResourceBundleData objects.
+*                           Added state table to govern parsing of files.
+*                           Modified to load locale index out of new file distinct
+*                           from default.txt.
+*   03/25/97    aliu        Modified to support 2-d arrays, needed for timezone data.
+*                           Added support for custom file suffixes.  Again, needed
+*                           to support timezone data.  Improved error handling to
+*                           detect duplicate tags and subtags.
+*   04/07/97    aliu        Fixed bug in getHashtableForLocale().  Fixed handling
+*                           of failing UErrorCode values on entry to API methods.
+*                           Fixed bugs in getArrayItem() for negative indices.
+*   04/29/97    aliu        Update to use new Hashtable deletion protocol.
+*   05/06/97    aliu        Flattened kTransitionTable for HP compiler.
+*                           Fixed usage of CharString.
+* 06/11/99      stephen     Removed parsing of .txt files.
+*                           Reworked to use new binary format.
+*                           Cleaned up.
+* 06/14/99      stephen     Removed methods taking a filename suffix.
+* 06/22/99      stephen     Added missing T_FileStream_close in parse()
+* 11/09/99      weiv        Added getLocale(), rewritten constructForLocale()
+* March 2000    weiv        complete overhaul.
+******************************************************************************
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/resbund.h"
+#include "umutex.h"
+
+#include "uresimp.h"
+
+U_NAMESPACE_BEGIN
+
+/*-----------------------------------------------------------------------------
+ * Implementation Notes
+ *
+ * Resource bundles are read in once, and thereafter cached.
+ * ResourceBundle statically keeps track of which files have been
+ * read, so we are guaranteed that each file is read at most once.
+ * Resource bundles can be loaded from different data directories and
+ * will be treated as distinct, even if they are for the same locale.
+ *
+ * Resource bundles are lightweight objects, which have pointers to
+ * one or more shared Hashtable objects containing all the data.
+ * Copying would be cheap, but there is no copy constructor, since
+ * there wasn't one in the original API.
+ *
+ * The ResourceBundle parsing mechanism is implemented as a transition
+ * network, for easy maintenance and modification.  The network is
+ * implemented as a matrix (instead of in code) to make this even
+ * easier.  The matrix contains Transition objects.  Each Transition
+ * object describes a destination node and an action to take before
+ * moving to the destination node.  The source node is encoded by the
+ * index of the object in the array that contains it.  The pieces
+ * needed to understand the transition network are the enums for node
+ * IDs and actions, the parse() method, which walks through the
+ * network and implements the actions, and the network itself.  The
+ * network guarantees certain conditions, for example, that a new
+ * resource will not be closed until one has been opened first; or
+ * that data will not be stored into a TaggedList until a TaggedList
+ * has been created.  Nonetheless, the code in parse() does some
+ * consistency checks as it runs the network, and fails with an
+ * U_INTERNAL_PROGRAM_ERROR if one of these checks fails.  If the input
+ * data has a bad format, an U_INVALID_FORMAT_ERROR is returned.  If you
+ * see an U_INTERNAL_PROGRAM_ERROR the transition matrix has a bug in
+ * it.
+ *
+ * Old functionality of multiple locales in a single file is still
+ * supported.  For this reason, LOCALE names override FILE names.  If
+ * data for en_US is located in the en.txt file, once it is loaded,
+ * the code will not care where it came from (other than remembering
+ * which directory it came from).  However, if there is an en_US
+ * resource in en_US.txt, that will take precedence.  There is no
+ * limit to the number or type of resources that can be stored in a
+ * file, however, files are only searched in a specific way.  If
+ * en_US_CA is requested, then first en_US_CA.txt is searched, then
+ * en_US.txt, then en.txt, then default.txt.  So it only makes sense
+ * to put certain locales in certain files.  In this example, it would
+ * be logical to put en_US_CA, en_US, and en into the en.txt file,
+ * since they would be found there if asked for.  The extreme example
+ * is to place all locale resources into default.txt, which should
+ * also work.
+ *
+ * Inheritance is implemented.  For example, xx_YY_zz inherits as
+ * follows: xx_YY_zz, xx_YY, xx, default.  Inheritance is implemented
+ * as an array of hashtables.  There will be from 1 to 4 hashtables in
+ * the array.
+ *
+ * Fallback files are implemented.  The fallback pattern is Language
+ * Country Variant (LCV) -> LC -> L.  Fallback is first done for the
+ * requested locale.  Then it is done for the default locale, as
+ * returned by Locale::getDefault().  Then the special file
+ * default.txt is searched for the default locale.  The overall FILE
+ * fallback path is LCV -> LC -> L -> dLCV -> dLC -> dL -> default.
+ *
+ * Note that although file name searching includes the default locale,
+ * once a ResourceBundle object is constructed, the inheritance path
+ * no longer includes the default locale.  The path is LCV -> LC -> L
+ * -> default.
+ *
+ * File parsing is lazy.  Nothing is parsed unless it is called for by
+ * someone.  So when a ResourceBundle for xx_YY_zz is constructed,
+ * only that locale is parsed (along with anything else in the same
+ * file).  Later, if the FooBar tag is asked for, and if it isn't
+ * found in xx_YY_zz, then xx_YY.txt will be parsed and checked, and
+ * so forth, until the chain is exhausted or the tag is found.
+ *
+ * Thread-safety is implemented around caches, both the cache that
+ * stores all the resouce data, and the cache that stores flags
+ * indicating whether or not a file has been visited.  These caches
+ * delete their storage at static cleanup time, when the process
+ * quits.
+ *
+ * ResourceBundle supports TableCollation as a special case.  This
+ * involves having special ResourceBundle objects which DO own their
+ * data, since we don't want large collation rule strings in the
+ * ResourceBundle cache (these are already cached in the
+ * TableCollation cache).  TableCollation files (.ctx files) have the
+ * same format as normal resource data files, with a different
+ * interpretation, from the standpoint of ResourceBundle.  .ctx files
+ * are loaded into otherwise ordinary ResourceBundle objects.  They
+ * don't inherit (that's implemented by TableCollation) and they own
+ * their data (as mentioned above).  However, they still support
+ * possible multiple locales in a single .ctx file.  (This is in
+ * practice a bad idea, since you only want the one locale you're
+ * looking for, and only one tag will be present
+ * ("CollationElements"), so you don't need an inheritance chain of
+ * multiple locales.)  Up to 4 locale resources will be loaded from a
+ * .ctx file; everything after the first 4 is ignored (parsed and
+ * deleted).  (Normal .txt files have no limit.)  Instead of being
+ * loaded into the cache, and then looked up as needed, the locale
+ * resources are read straight into the ResourceBundle object.
+ *
+ * The Index, which used to reside in default.txt, has been moved to a
+ * new file, index.txt.  This file contains a slightly modified format
+ * with the addition of the "InstalledLocales" tag; it looks like:
+ *
+ * Index {
+ *   InstalledLocales {
+ *     ar
+ *     ..
+ *     zh_TW
+ *   }
+ * }
+ */
+//-----------------------------------------------------------------------------
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ResourceBundle)
+
+ResourceBundle::ResourceBundle(UErrorCode &err)
+                                :UObject(), fLocale(NULL)
+{
+    fResource = ures_open(0, Locale::getDefault().getName(), &err);
+}
+
+ResourceBundle::ResourceBundle(const ResourceBundle &other)
+                              :UObject(other), fLocale(NULL)
+{
+    UErrorCode status = U_ZERO_ERROR;
+
+    if (other.fResource) {
+        fResource = ures_copyResb(0, other.fResource, &status);
+    } else {
+        /* Copying a bad resource bundle */
+        fResource = NULL;
+    }
+}
+
+ResourceBundle::ResourceBundle(UResourceBundle *res, UErrorCode& err)
+                               :UObject(), fLocale(NULL)
+{
+    if (res) {
+        fResource = ures_copyResb(0, res, &err);
+    } else {
+        /* Copying a bad resource bundle */
+        fResource = NULL;
+    }
+}
+
+ResourceBundle::ResourceBundle(const char* path, const Locale& locale, UErrorCode& err) 
+                               :UObject(), fLocale(NULL)
+{
+    fResource = ures_open(path, locale.getName(), &err);
+}
+
+
+ResourceBundle& ResourceBundle::operator=(const ResourceBundle& other)
+{
+    if(this == &other) {
+        return *this;
+    }
+    if(fResource != 0) {
+        ures_close(fResource);
+        fResource = NULL;
+    }
+    UErrorCode status = U_ZERO_ERROR;
+    if (other.fResource) {
+        fResource = ures_copyResb(0, other.fResource, &status);
+    } else {
+        /* Copying a bad resource bundle */
+        fResource = NULL;
+    }
+    return *this;
+}
+
+ResourceBundle::~ResourceBundle()
+{
+    if(fResource != 0) {
+        ures_close(fResource);
+    }
+    if(fLocale != NULL) {
+      delete(fLocale);
+    }
+}
+
+ResourceBundle *
+ResourceBundle::clone() const {
+    return new ResourceBundle(*this);
+}
+
+UnicodeString ResourceBundle::getString(UErrorCode& status) const {
+    int32_t len = 0;
+    const UChar *r = ures_getString(fResource, &len, &status);
+    return UnicodeString(TRUE, r, len);
+}
+
+const uint8_t *ResourceBundle::getBinary(int32_t& len, UErrorCode& status) const {
+    return ures_getBinary(fResource, &len, &status);
+}
+
+const int32_t *ResourceBundle::getIntVector(int32_t& len, UErrorCode& status) const {
+    return ures_getIntVector(fResource, &len, &status);
+}
+
+uint32_t ResourceBundle::getUInt(UErrorCode& status) const {
+    return ures_getUInt(fResource, &status);
+}
+
+int32_t ResourceBundle::getInt(UErrorCode& status) const {
+    return ures_getInt(fResource, &status);
+}
+
+const char *ResourceBundle::getName(void) const {
+    return ures_getName(fResource);
+}
+
+const char *ResourceBundle::getKey(void) const {
+    return ures_getKey(fResource);
+}
+
+UResType ResourceBundle::getType(void) const {
+    return ures_getType(fResource);
+}
+
+int32_t ResourceBundle::getSize(void) const {
+    return ures_getSize(fResource);
+}
+
+UBool ResourceBundle::hasNext(void) const {
+    return ures_hasNext(fResource);
+}
+
+void ResourceBundle::resetIterator(void) {
+    ures_resetIterator(fResource);
+}
+
+ResourceBundle ResourceBundle::getNext(UErrorCode& status) {
+    UResourceBundle r;
+
+    ures_initStackObject(&r);
+    ures_getNextResource(fResource, &r, &status);
+    ResourceBundle res(&r, status);
+    if (U_SUCCESS(status)) {
+        ures_close(&r);
+    }
+    return res;
+}
+
+UnicodeString ResourceBundle::getNextString(UErrorCode& status) {
+    int32_t len = 0;
+    const UChar* r = ures_getNextString(fResource, &len, 0, &status);
+    return UnicodeString(TRUE, r, len);
+}
+
+UnicodeString ResourceBundle::getNextString(const char ** key, UErrorCode& status) {
+    int32_t len = 0;
+    const UChar* r = ures_getNextString(fResource, &len, key, &status);
+    return UnicodeString(TRUE, r, len);
+}
+
+ResourceBundle ResourceBundle::get(int32_t indexR, UErrorCode& status) const {
+    UResourceBundle r;
+
+    ures_initStackObject(&r);
+    ures_getByIndex(fResource, indexR, &r, &status);
+    ResourceBundle res(&r, status);
+    if (U_SUCCESS(status)) {
+        ures_close(&r);
+    }
+    return res;
+}
+
+UnicodeString ResourceBundle::getStringEx(int32_t indexS, UErrorCode& status) const {
+    int32_t len = 0;
+    const UChar* r = ures_getStringByIndex(fResource, indexS, &len, &status);
+    return UnicodeString(TRUE, r, len);
+}
+
+ResourceBundle ResourceBundle::get(const char* key, UErrorCode& status) const {
+    UResourceBundle r;
+
+    ures_initStackObject(&r);
+    ures_getByKey(fResource, key, &r, &status);
+    ResourceBundle res(&r, status);
+    if (U_SUCCESS(status)) {
+        ures_close(&r);
+    }
+    return res;
+}
+
+ResourceBundle ResourceBundle::getWithFallback(const char* key, UErrorCode& status){
+    UResourceBundle r;
+    ures_initStackObject(&r);
+    ures_getByKeyWithFallback(fResource, key, &r, &status);
+    ResourceBundle res(&r, status);
+    if(U_SUCCESS(status)){
+        ures_close(&r);
+    }
+    return res;
+}
+UnicodeString ResourceBundle::getStringEx(const char* key, UErrorCode& status) const {
+    int32_t len = 0;
+    const UChar* r = ures_getStringByKey(fResource, key, &len, &status);
+    return UnicodeString(TRUE, r, len);
+}
+
+const char*
+ResourceBundle::getVersionNumber()  const
+{
+    return ures_getVersionNumber(fResource);
+}
+
+void ResourceBundle::getVersion(UVersionInfo versionInfo) const {
+    ures_getVersion(fResource, versionInfo);
+}
+
+const Locale &ResourceBundle::getLocale(void) const
+{
+    UBool needInit;
+    UMTX_CHECK(NULL, (fLocale == NULL), needInit);
+    if(needInit) {
+        UErrorCode status = U_ZERO_ERROR;
+        const char *localeName = ures_getLocale(fResource, &status);
+        Locale  *tLocale = new Locale(localeName);
+        // Null pointer check
+        if (tLocale == NULL) {
+        	return Locale::getDefault(); // Return default locale if one could not be created.
+        }
+        umtx_lock(NULL);
+        ResourceBundle *me = (ResourceBundle *)this; // semantically const
+        if (me->fLocale == NULL) {
+            me->fLocale = tLocale;
+            tLocale = NULL;
+        }
+        umtx_unlock(NULL);
+        delete tLocale;
+    }
+    return *fLocale;
+}
+
+const Locale ResourceBundle::getLocale(ULocDataLocaleType type, UErrorCode &status) const
+{
+  return ures_getLocaleByType(fResource, type, &status);
+}
+
+//eof
+U_NAMESPACE_END
diff --git a/icu/source/common/resbund_cnv.cpp b/icu/source/common/resbund_cnv.cpp
new file mode 100644
index 0000000..a18e57e
--- /dev/null
+++ b/icu/source/common/resbund_cnv.cpp
@@ -0,0 +1,55 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 1997-2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  resbund_cnv.cpp
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2004aug25
+*   created by: Markus W. Scherer
+*
+*   Character conversion functions moved here from resbund.cpp
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/resbund.h"
+#include "uinvchar.h"
+
+U_NAMESPACE_BEGIN
+
+ResourceBundle::ResourceBundle( const UnicodeString&    path,
+                                const Locale&           locale,
+                                UErrorCode&              error)
+                                :UObject(), fLocale(NULL)
+{
+    constructForLocale(path, locale, error);
+}
+
+ResourceBundle::ResourceBundle( const UnicodeString&    path,
+                                UErrorCode&              error)
+                                :UObject(), fLocale(NULL)
+{
+    constructForLocale(path, Locale::getDefault(), error);
+}
+
+void 
+ResourceBundle::constructForLocale(const UnicodeString& path,
+                                   const Locale& locale,
+                                   UErrorCode& error)
+{
+    if (path.isEmpty()) {
+        fResource = ures_open(NULL, locale.getName(), &error);
+    }
+    else {
+        UnicodeString nullTerminatedPath(path);
+        nullTerminatedPath.append((UChar)0);
+        fResource = ures_openU(nullTerminatedPath.getBuffer(), locale.getName(), &error);
+    }
+}
+
+U_NAMESPACE_END
diff --git a/icu/source/common/ruleiter.cpp b/icu/source/common/ruleiter.cpp
new file mode 100644
index 0000000..b99a831
--- /dev/null
+++ b/icu/source/common/ruleiter.cpp
@@ -0,0 +1,160 @@
+/*
+**********************************************************************
+* Copyright (c) 2003-2007, International Business Machines
+* Corporation and others.  All Rights Reserved.
+**********************************************************************
+* Author: Alan Liu
+* Created: September 24 2003
+* Since: ICU 2.8
+**********************************************************************
+*/
+#include "ruleiter.h"
+#include "unicode/parsepos.h"
+#include "unicode/unistr.h"
+#include "unicode/symtable.h"
+#include "util.h"
+
+/* \U87654321 or \ud800\udc00 */
+#define MAX_U_NOTATION_LEN 12
+
+U_NAMESPACE_BEGIN
+
+RuleCharacterIterator::RuleCharacterIterator(const UnicodeString& theText, const SymbolTable* theSym,
+                      ParsePosition& thePos) :
+    text(theText),
+    pos(thePos),
+    sym(theSym),
+    buf(0),
+    bufPos(0)
+{}
+
+UBool RuleCharacterIterator::atEnd() const {
+    return buf == 0 && pos.getIndex() == text.length();
+}
+
+UChar32 RuleCharacterIterator::next(int32_t options, UBool& isEscaped, UErrorCode& ec) {
+    if (U_FAILURE(ec)) return DONE;
+
+    UChar32 c = DONE;
+    isEscaped = FALSE;
+
+    for (;;) {
+        c = _current();
+        _advance(UTF_CHAR_LENGTH(c));
+
+        if (c == SymbolTable::SYMBOL_REF && buf == 0 &&
+            (options & PARSE_VARIABLES) != 0 && sym != 0) {
+            UnicodeString name = sym->parseReference(text, pos, text.length());
+            // If name is empty there was an isolated SYMBOL_REF;
+            // return it.  Caller must be prepared for this.
+            if (name.length() == 0) {
+                break;
+            }
+            bufPos = 0;
+            buf = sym->lookup(name);
+            if (buf == 0) {
+                ec = U_UNDEFINED_VARIABLE;
+                return DONE;
+            }
+            // Handle empty variable value
+            if (buf->length() == 0) {
+                buf = 0;
+            }
+            continue;
+        }
+
+        if ((options & SKIP_WHITESPACE) != 0 &&
+            uprv_isRuleWhiteSpace(c)) {
+            continue;
+        }
+
+        if (c == 0x5C /*'\\'*/ && (options & PARSE_ESCAPES) != 0) {
+            UnicodeString tempEscape;
+            int32_t offset = 0;
+            c = lookahead(tempEscape, MAX_U_NOTATION_LEN).unescapeAt(offset);
+            jumpahead(offset);
+            isEscaped = TRUE;
+            if (c < 0) {
+                ec = U_MALFORMED_UNICODE_ESCAPE;
+                return DONE;
+            }
+        }
+
+        break;
+    }
+
+    return c;
+}
+
+void RuleCharacterIterator::getPos(RuleCharacterIterator::Pos& p) const {
+    p.buf = buf;
+    p.pos = pos.getIndex();
+    p.bufPos = bufPos;
+}
+
+void RuleCharacterIterator::setPos(const RuleCharacterIterator::Pos& p) {
+    buf = p.buf;
+    pos.setIndex(p.pos);
+    bufPos = p.bufPos;
+}
+
+void RuleCharacterIterator::skipIgnored(int32_t options) {
+    if ((options & SKIP_WHITESPACE) != 0) {
+        for (;;) {
+            UChar32 a = _current();
+            if (!uprv_isRuleWhiteSpace(a)) break;
+            _advance(UTF_CHAR_LENGTH(a));
+        }
+    }
+}
+
+UnicodeString& RuleCharacterIterator::lookahead(UnicodeString& result, int32_t maxLookAhead) const {
+    if (maxLookAhead < 0) {
+        maxLookAhead = 0x7FFFFFFF;
+    }
+    if (buf != 0) {
+        buf->extract(bufPos, maxLookAhead, result);
+    } else {
+        text.extract(pos.getIndex(), maxLookAhead, result);
+    }
+    return result;
+}
+
+void RuleCharacterIterator::jumpahead(int32_t count) {
+    _advance(count);
+}
+
+/*
+UnicodeString& RuleCharacterIterator::toString(UnicodeString& result) const {
+    int32_t b = pos.getIndex();
+    text.extract(0, b, result);
+    return result.append((UChar) 0x7C).append(text, b, 0x7FFFFFFF); // Insert '|' at index
+}
+*/
+
+UChar32 RuleCharacterIterator::_current() const {
+    if (buf != 0) {
+        return buf->char32At(bufPos);
+    } else {
+        int i = pos.getIndex();
+        return (i < text.length()) ? text.char32At(i) : (UChar32)DONE;
+    }
+}
+
+void RuleCharacterIterator::_advance(int32_t count) {
+    if (buf != 0) {
+        bufPos += count;
+        if (bufPos == buf->length()) {
+            buf = 0;
+        }
+    } else {
+        pos.setIndex(pos.getIndex() + count);
+        if (pos.getIndex() > text.length()) {
+            pos.setIndex(text.length());
+        }
+    }
+}
+
+U_NAMESPACE_END
+
+//eof
diff --git a/icu/source/common/ruleiter.h b/icu/source/common/ruleiter.h
new file mode 100644
index 0000000..cc4e847
--- /dev/null
+++ b/icu/source/common/ruleiter.h
@@ -0,0 +1,232 @@
+/*
+**********************************************************************
+* Copyright (c) 2003-2007, International Business Machines
+* Corporation and others.  All Rights Reserved.
+**********************************************************************
+* Author: Alan Liu
+* Created: September 24 2003
+* Since: ICU 2.8
+**********************************************************************
+*/
+#ifndef _RULEITER_H_
+#define _RULEITER_H_
+
+#include "unicode/uobject.h"
+
+U_NAMESPACE_BEGIN
+
+class UnicodeString;
+class ParsePosition;
+class SymbolTable;
+
+/**
+ * An iterator that returns 32-bit code points.  This class is deliberately
+ * <em>not</em> related to any of the ICU character iterator classes
+ * in order to minimize complexity.
+ * @author Alan Liu
+ * @since ICU 2.8
+ */
+class RuleCharacterIterator : public UMemory {
+
+    // TODO: Ideas for later.  (Do not implement if not needed, lest the
+    // code coverage numbers go down due to unused methods.)
+    // 1. Add a copy constructor, operator==() method.
+    // 2. Rather than return DONE, throw an exception if the end
+    // is reached -- this is an alternate usage model, probably not useful.
+
+private:
+    /**
+     * Text being iterated.
+     */    
+    const UnicodeString& text;
+
+    /**
+     * Position of iterator.
+     */
+    ParsePosition& pos;
+
+    /**
+     * Symbol table used to parse and dereference variables.  May be 0.
+     */
+    const SymbolTable* sym;
+    
+    /**
+     * Current variable expansion, or 0 if none.
+     */
+    const UnicodeString* buf;
+
+    /**
+     * Position within buf.  Meaningless if buf == 0.
+     */
+    int32_t bufPos;
+
+public:
+    /**
+     * Value returned when there are no more characters to iterate.
+     */
+    enum { DONE = -1 };
+
+    /**
+     * Bitmask option to enable parsing of variable names.  If (options &
+     * PARSE_VARIABLES) != 0, then an embedded variable will be expanded to
+     * its value.  Variables are parsed using the SymbolTable API.
+     */
+    enum { PARSE_VARIABLES = 1 };
+
+    /**
+     * Bitmask option to enable parsing of escape sequences.  If (options &
+     * PARSE_ESCAPES) != 0, then an embedded escape sequence will be expanded
+     * to its value.  Escapes are parsed using Utility.unescapeAt().
+     */
+    enum { PARSE_ESCAPES   = 2 };
+
+    /**
+     * Bitmask option to enable skipping of whitespace.  If (options &
+     * SKIP_WHITESPACE) != 0, then whitespace characters will be silently
+     * skipped, as if they were not present in the input.  Whitespace
+     * characters are defined by UCharacterProperty.isRuleWhiteSpace().
+     */
+    enum { SKIP_WHITESPACE = 4 };
+
+    /**
+     * Constructs an iterator over the given text, starting at the given
+     * position.
+     * @param text the text to be iterated
+     * @param sym the symbol table, or null if there is none.  If sym is null,
+     * then variables will not be deferenced, even if the PARSE_VARIABLES
+     * option is set.
+     * @param pos upon input, the index of the next character to return.  If a
+     * variable has been dereferenced, then pos will <em>not</em> increment as
+     * characters of the variable value are iterated.
+     */
+    RuleCharacterIterator(const UnicodeString& text, const SymbolTable* sym,
+                          ParsePosition& pos);
+    
+    /**
+     * Returns true if this iterator has no more characters to return.
+     */
+    UBool atEnd() const;
+
+    /**
+     * Returns the next character using the given options, or DONE if there
+     * are no more characters, and advance the position to the next
+     * character.
+     * @param options one or more of the following options, bitwise-OR-ed
+     * together: PARSE_VARIABLES, PARSE_ESCAPES, SKIP_WHITESPACE.
+     * @param isEscaped output parameter set to TRUE if the character
+     * was escaped
+     * @param ec input-output error code.  An error will only be set by
+     * this routing if options includes PARSE_VARIABLES and an unknown
+     * variable name is seen, or if options includes PARSE_ESCAPES and
+     * an invalid escape sequence is seen.
+     * @return the current 32-bit code point, or DONE
+     */
+    UChar32 next(int32_t options, UBool& isEscaped, UErrorCode& ec);
+
+    /**
+     * Returns true if this iterator is currently within a variable expansion.
+     */
+    inline UBool inVariable() const;
+
+    /**
+     * An opaque object representing the position of a RuleCharacterIterator.
+     */
+    struct Pos : public UMemory {
+    private:
+        const UnicodeString* buf;
+        int32_t pos;
+        int32_t bufPos;
+        friend class RuleCharacterIterator;
+    };
+
+    /**
+     * Sets an object which, when later passed to setPos(), will
+     * restore this iterator's position.  Usage idiom:
+     *
+     * RuleCharacterIterator iterator = ...;
+     * RuleCharacterIterator::Pos pos;
+     * iterator.getPos(pos);
+     * for (;;) {
+     *   iterator.getPos(pos);
+     *   int c = iterator.next(...);
+     *   ...
+     * }
+     * iterator.setPos(pos);
+     *
+     * @param p a position object to be set to this iterator's
+     * current position.
+     */
+    void getPos(Pos& p) const;
+
+    /**
+     * Restores this iterator to the position it had when getPos()
+     * set the given object.
+     * @param p a position object previously set by getPos()
+     */
+    void setPos(const Pos& p);
+
+    /**
+     * Skips ahead past any ignored characters, as indicated by the given
+     * options.  This is useful in conjunction with the lookahead() method.
+     *
+     * Currently, this only has an effect for SKIP_WHITESPACE.
+     * @param options one or more of the following options, bitwise-OR-ed
+     * together: PARSE_VARIABLES, PARSE_ESCAPES, SKIP_WHITESPACE.
+     */
+    void skipIgnored(int32_t options);
+
+    /**
+     * Returns a string containing the remainder of the characters to be
+     * returned by this iterator, without any option processing.  If the
+     * iterator is currently within a variable expansion, this will only
+     * extend to the end of the variable expansion.  This method is provided
+     * so that iterators may interoperate with string-based APIs.  The typical
+     * sequence of calls is to call skipIgnored(), then call lookahead(), then
+     * parse the string returned by lookahead(), then call jumpahead() to
+     * resynchronize the iterator.
+     * @param result a string to receive the characters to be returned
+     * by future calls to next()
+     * @param maxLookAhead The maximum to copy into the result.
+     * @return a reference to result
+     */
+    UnicodeString& lookahead(UnicodeString& result, int32_t maxLookAhead = -1) const;
+
+    /**
+     * Advances the position by the given number of 16-bit code units.
+     * This is useful in conjunction with the lookahead() method.
+     * @param count the number of 16-bit code units to jump over
+     */
+    void jumpahead(int32_t count);
+
+    /**
+     * Returns a string representation of this object, consisting of the
+     * characters being iterated, with a '|' marking the current position.
+     * Position within an expanded variable is <em>not</em> indicated.
+     * @param result output parameter to receive a string
+     * representation of this object
+     */
+//    UnicodeString& toString(UnicodeString& result) const;
+    
+private:
+    /**
+     * Returns the current 32-bit code point without parsing escapes, parsing
+     * variables, or skipping whitespace.
+     * @return the current 32-bit code point
+     */
+    UChar32 _current() const;
+    
+    /**
+     * Advances the position by the given amount.
+     * @param count the number of 16-bit code units to advance past
+     */
+    void _advance(int32_t count);
+};
+
+inline UBool RuleCharacterIterator::inVariable() const {
+    return buf != 0;
+}
+
+U_NAMESPACE_END
+
+#endif // _RULEITER_H_
+//eof
diff --git a/icu/source/common/schriter.cpp b/icu/source/common/schriter.cpp
new file mode 100644
index 0000000..c6c4244
--- /dev/null
+++ b/icu/source/common/schriter.cpp
@@ -0,0 +1,115 @@
+/*
+******************************************************************************
+* Copyright (C) 1998-2007, International Business Machines Corporation and   *
+* others. All Rights Reserved.                                               *
+******************************************************************************
+*
+* File schriter.cpp
+*
+* Modification History:
+*
+*   Date        Name        Description
+*  05/05/99     stephen     Cleaned up.
+******************************************************************************
+*/
+
+#include "unicode/chariter.h"
+#include "unicode/schriter.h"
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(StringCharacterIterator)
+
+StringCharacterIterator::StringCharacterIterator()
+  : UCharCharacterIterator(),
+    text()
+{
+  // NEVER DEFAULT CONSTRUCT!
+}
+
+StringCharacterIterator::StringCharacterIterator(const UnicodeString& textStr)
+  : UCharCharacterIterator(textStr.getBuffer(), textStr.length()),
+    text(textStr)
+{
+    // we had set the input parameter's array, now we need to set our copy's array
+    UCharCharacterIterator::text = this->text.getBuffer();
+}
+
+StringCharacterIterator::StringCharacterIterator(const UnicodeString& textStr,
+                                                 int32_t textPos)
+  : UCharCharacterIterator(textStr.getBuffer(), textStr.length(), textPos),
+    text(textStr)
+{
+    // we had set the input parameter's array, now we need to set our copy's array
+    UCharCharacterIterator::text = this->text.getBuffer();
+}
+
+StringCharacterIterator::StringCharacterIterator(const UnicodeString& textStr,
+                                                 int32_t textBegin,
+                                                 int32_t textEnd,
+                                                 int32_t textPos)
+  : UCharCharacterIterator(textStr.getBuffer(), textStr.length(), textBegin, textEnd, textPos),
+    text(textStr)
+{
+    // we had set the input parameter's array, now we need to set our copy's array
+    UCharCharacterIterator::text = this->text.getBuffer();
+}
+
+StringCharacterIterator::StringCharacterIterator(const StringCharacterIterator& that)
+  : UCharCharacterIterator(that),
+    text(that.text)
+{
+    // we had set the input parameter's array, now we need to set our copy's array
+    UCharCharacterIterator::text = this->text.getBuffer();
+}
+
+StringCharacterIterator::~StringCharacterIterator() {
+}
+
+StringCharacterIterator&
+StringCharacterIterator::operator=(const StringCharacterIterator& that) {
+    UCharCharacterIterator::operator=(that);
+    text = that.text;
+    // we had set the input parameter's array, now we need to set our copy's array
+    UCharCharacterIterator::text = this->text.getBuffer();
+    return *this;
+}
+
+UBool
+StringCharacterIterator::operator==(const ForwardCharacterIterator& that) const {
+    if (this == &that) {
+        return TRUE;
+    }
+
+    // do not call UCharCharacterIterator::operator==()
+    // because that checks for array pointer equality
+    // while we compare UnicodeString objects
+
+    if (getDynamicClassID() != that.getDynamicClassID()) {
+        return FALSE;
+    }
+
+    StringCharacterIterator&    realThat = (StringCharacterIterator&)that;
+
+    return text == realThat.text
+        && pos == realThat.pos
+        && begin == realThat.begin
+        && end == realThat.end;
+}
+
+CharacterIterator*
+StringCharacterIterator::clone() const {
+    return new StringCharacterIterator(*this);
+}
+
+void
+StringCharacterIterator::setText(const UnicodeString& newText) {
+    text = newText;
+    UCharCharacterIterator::setText(text.getBuffer(), text.length());
+}
+
+void
+StringCharacterIterator::getText(UnicodeString& result) {
+    result = text;
+}
+U_NAMESPACE_END
diff --git a/icu/source/common/serv.cpp b/icu/source/common/serv.cpp
new file mode 100644
index 0000000..f94fd43
--- /dev/null
+++ b/icu/source/common/serv.cpp
@@ -0,0 +1,981 @@
+/**
+*******************************************************************************
+* Copyright (C) 2001-2008, International Business Machines Corporation.       *
+* All Rights Reserved.                                                        *
+*******************************************************************************
+*/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_SERVICE
+
+#include "serv.h"
+#include "umutex.h"
+
+#undef SERVICE_REFCOUNT
+
+// in case we use the refcount stuff
+
+U_NAMESPACE_BEGIN
+
+/*
+******************************************************************
+*/
+
+const UChar ICUServiceKey::PREFIX_DELIMITER = 0x002F;   /* '/' */
+
+ICUServiceKey::ICUServiceKey(const UnicodeString& id) 
+: _id(id) {
+}
+
+ICUServiceKey::~ICUServiceKey() 
+{
+}
+
+const UnicodeString& 
+ICUServiceKey::getID() const 
+{
+    return _id;
+}
+
+UnicodeString& 
+ICUServiceKey::canonicalID(UnicodeString& result) const 
+{
+    return result.append(_id);
+}
+
+UnicodeString& 
+ICUServiceKey::currentID(UnicodeString& result) const 
+{
+    return canonicalID(result);
+}
+
+UnicodeString& 
+ICUServiceKey::currentDescriptor(UnicodeString& result) const 
+{
+    prefix(result);
+    result.append(PREFIX_DELIMITER);
+    return currentID(result);
+}
+
+UBool 
+ICUServiceKey::fallback() 
+{
+    return FALSE;
+}
+
+UBool 
+ICUServiceKey::isFallbackOf(const UnicodeString& id) const 
+{
+    return id == _id;
+}
+
+UnicodeString& 
+ICUServiceKey::prefix(UnicodeString& result) const 
+{
+    return result;
+}
+
+UnicodeString& 
+ICUServiceKey::parsePrefix(UnicodeString& result) 
+{
+    int32_t n = result.indexOf(PREFIX_DELIMITER);
+    if (n < 0) {
+        n = 0;
+    }
+    result.remove(n);
+    return result;
+}
+
+UnicodeString& 
+ICUServiceKey::parseSuffix(UnicodeString& result) 
+{
+    int32_t n = result.indexOf(PREFIX_DELIMITER);
+    if (n >= 0) {
+        result.remove(0, n+1);
+    }
+    return result;
+}
+
+#ifdef SERVICE_DEBUG
+UnicodeString& 
+ICUServiceKey::debug(UnicodeString& result) const 
+{
+    debugClass(result);
+    result.append(" id: ");
+    result.append(_id);
+    return result;
+}
+
+UnicodeString& 
+ICUServiceKey::debugClass(UnicodeString& result) const 
+{
+    return result.append("ICUServiceKey");
+}
+#endif
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ICUServiceKey)
+
+/*
+******************************************************************
+*/
+
+SimpleFactory::SimpleFactory(UObject* instanceToAdopt, const UnicodeString& id, UBool visible) 
+: _instance(instanceToAdopt), _id(id), _visible(visible)
+{
+}
+
+SimpleFactory::~SimpleFactory() 
+{
+    delete _instance;
+}
+
+UObject* 
+SimpleFactory::create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const 
+{
+    if (U_SUCCESS(status)) {
+        UnicodeString temp;
+        if (_id == key.currentID(temp)) {
+            return service->cloneInstance(_instance); 
+        }
+    }
+    return NULL;
+}
+
+void 
+SimpleFactory::updateVisibleIDs(Hashtable& result, UErrorCode& status) const 
+{
+    if (_visible) {
+        result.put(_id, (void*)this, status); // cast away const
+    } else {
+        result.remove(_id);
+    }
+}
+
+UnicodeString& 
+SimpleFactory::getDisplayName(const UnicodeString& id, const Locale& /* locale */, UnicodeString& result) const 
+{
+    if (_visible && _id == id) {
+        result = _id;
+    } else {
+        result.setToBogus();
+    }
+    return result;
+}
+
+#ifdef SERVICE_DEBUG
+UnicodeString& 
+SimpleFactory::debug(UnicodeString& toAppendTo) const 
+{
+    debugClass(toAppendTo);
+    toAppendTo.append(" id: ");
+    toAppendTo.append(_id);
+    toAppendTo.append(", visible: ");
+    toAppendTo.append(_visible ? "T" : "F");
+    return toAppendTo;
+}
+
+UnicodeString& 
+SimpleFactory::debugClass(UnicodeString& toAppendTo) const 
+{
+    return toAppendTo.append("SimpleFactory");
+}
+#endif
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleFactory)
+
+/*
+******************************************************************
+*/
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ServiceListener)
+
+/*
+******************************************************************
+*/
+
+// Record the actual id for this service in the cache, so we can return it
+// even if we succeed later with a different id.
+class CacheEntry : public UMemory {
+private:
+    int32_t refcount;
+
+public:
+    UnicodeString actualDescriptor;
+    UObject* service;
+
+    /**
+    * Releases a reference to the shared resource.
+    */
+    ~CacheEntry() {
+        delete service;
+    }
+
+    CacheEntry(const UnicodeString& _actualDescriptor, UObject* _service) 
+        : refcount(1), actualDescriptor(_actualDescriptor), service(_service) {
+    }
+
+    /**
+    * Instantiation creates an initial reference, so don't call this
+    * unless you're creating a new pointer to this.  Management of
+    * that pointer will have to know how to deal with refcounts.  
+    * Return true if the resource has not already been released.
+    */
+    CacheEntry* ref() {
+        ++refcount;
+        return this;
+    }
+
+    /**
+    * Destructions removes a reference, so don't call this unless
+    * you're removing pointer to this somewhere.  Management of that
+    * pointer will have to know how to deal with refcounts.  Once
+    * the refcount drops to zero, the resource is released.  Return
+    * false if the resouce has been released.
+    */
+    CacheEntry* unref() {
+        if ((--refcount) == 0) {
+            delete this;
+            return NULL;
+        }
+        return this;
+    }
+
+    /**
+    * Return TRUE if there is at least one reference to this and the
+    * resource has not been released.
+    */
+    UBool isShared() const {
+        return refcount > 1;
+    }
+};
+
+// UObjectDeleter for serviceCache
+U_CDECL_BEGIN
+static void U_CALLCONV
+cacheDeleter(void* obj) {
+    U_NAMESPACE_USE ((CacheEntry*)obj)->unref();
+}
+
+/**
+* Deleter for UObjects
+*/
+static void U_CALLCONV
+deleteUObject(void *obj) {
+    U_NAMESPACE_USE delete (UObject*) obj;
+}
+U_CDECL_END
+
+/*
+******************************************************************
+*/
+
+class DNCache : public UMemory {
+public:
+    Hashtable cache;
+    const Locale locale;
+
+    DNCache(const Locale& _locale) 
+        : cache(), locale(_locale) 
+    {
+        // cache.setKeyDeleter(uhash_deleteUnicodeString);
+    }
+};
+
+
+/*
+******************************************************************
+*/
+
+StringPair* 
+StringPair::create(const UnicodeString& displayName, 
+                   const UnicodeString& id,
+                   UErrorCode& status)
+{
+    if (U_SUCCESS(status)) {
+        StringPair* sp = new StringPair(displayName, id);
+        if (sp == NULL || sp->isBogus()) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            delete sp;
+            return NULL;
+        }
+        return sp;
+    }
+    return NULL;
+}
+
+UBool 
+StringPair::isBogus() const {
+    return displayName.isBogus() || id.isBogus();
+}
+
+StringPair::StringPair(const UnicodeString& _displayName, 
+                       const UnicodeString& _id)
+: displayName(_displayName)
+, id(_id)
+{
+}
+
+U_CDECL_BEGIN
+static void U_CALLCONV
+userv_deleteStringPair(void *obj) {
+    U_NAMESPACE_USE delete (StringPair*) obj;
+}
+U_CDECL_END
+
+/*
+******************************************************************
+*/
+
+ICUService::ICUService()
+: name()
+, lock(0)
+, timestamp(0)
+, factories(NULL)
+, serviceCache(NULL)
+, idCache(NULL)
+, dnCache(NULL)
+{
+    umtx_init(&lock);
+}
+
+ICUService::ICUService(const UnicodeString& newName) 
+: name(newName)
+, lock(0)
+, timestamp(0)
+, factories(NULL)
+, serviceCache(NULL)
+, idCache(NULL)
+, dnCache(NULL)
+{
+    umtx_init(&lock);
+}
+
+ICUService::~ICUService()
+{
+    {
+        Mutex mutex(&lock);
+        clearCaches();
+        delete factories;
+        factories = NULL;
+    }
+    umtx_destroy(&lock);
+}
+
+UObject* 
+ICUService::get(const UnicodeString& descriptor, UErrorCode& status) const 
+{
+    return get(descriptor, NULL, status);
+}
+
+UObject* 
+ICUService::get(const UnicodeString& descriptor, UnicodeString* actualReturn, UErrorCode& status) const 
+{
+    UObject* result = NULL;
+    ICUServiceKey* key = createKey(&descriptor, status);
+    if (key) {
+        result = getKey(*key, actualReturn, status);
+        delete key;
+    }
+    return result;
+}
+
+UObject* 
+ICUService::getKey(ICUServiceKey& key, UErrorCode& status) const 
+{
+    return getKey(key, NULL, status);
+}
+
+// this is a vector that subclasses of ICUService can override to further customize the result object
+// before returning it.  All other public get functions should call this one.
+
+UObject* 
+ICUService::getKey(ICUServiceKey& key, UnicodeString* actualReturn, UErrorCode& status) const 
+{
+    return getKey(key, actualReturn, NULL, status);
+}
+
+// make it possible to call reentrantly on systems that don't have reentrant mutexes.
+// we can use this simple approach since we know the situation where we're calling
+// reentrantly even without knowing the thread.
+class XMutex : public UMemory {
+public:
+    inline XMutex(UMTX *mutex, UBool reentering) 
+        : fMutex(mutex)
+        , fActive(!reentering) 
+    {
+        if (fActive) umtx_lock(fMutex);
+    }
+    inline ~XMutex() {
+        if (fActive) umtx_unlock(fMutex);
+    }
+
+private:
+    UMTX  *fMutex;
+    UBool fActive;
+};
+
+struct UVectorDeleter {
+    UVector* _obj;
+    UVectorDeleter() : _obj(NULL) {}
+    ~UVectorDeleter() { delete _obj; }
+};
+
+// called only by factories, treat as private
+UObject* 
+ICUService::getKey(ICUServiceKey& key, UnicodeString* actualReturn, const ICUServiceFactory* factory, UErrorCode& status) const 
+{
+    if (U_FAILURE(status)) {
+        return NULL;
+    }
+
+    if (isDefault()) {
+        return handleDefault(key, actualReturn, status);
+    }
+
+    ICUService* ncthis = (ICUService*)this; // cast away semantic const
+
+    CacheEntry* result = NULL;
+    {
+        // The factory list can't be modified until we're done, 
+        // otherwise we might update the cache with an invalid result.
+        // The cache has to stay in synch with the factory list.
+        // ICU doesn't have monitors so we can't use rw locks, so 
+        // we single-thread everything using this service, for now.
+
+        // if factory is not null, we're calling from within the mutex,
+        // and since some unix machines don't have reentrant mutexes we
+        // need to make sure not to try to lock it again.
+        XMutex mutex(&ncthis->lock, factory != NULL);
+
+        if (serviceCache == NULL) {
+            ncthis->serviceCache = new Hashtable(status);
+            if (ncthis->serviceCache == NULL) {
+                return NULL;
+            }
+            if (U_FAILURE(status)) {
+                delete serviceCache;
+                return NULL;
+            }
+            serviceCache->setValueDeleter(cacheDeleter);
+        }
+
+        UnicodeString currentDescriptor;
+        UVectorDeleter cacheDescriptorList;
+        UBool putInCache = FALSE;
+
+        int32_t startIndex = 0;
+        int32_t limit = factories->size();
+        UBool cacheResult = TRUE;
+
+        if (factory != NULL) {
+            for (int32_t i = 0; i < limit; ++i) {
+                if (factory == (const ICUServiceFactory*)factories->elementAt(i)) {
+                    startIndex = i + 1;
+                    break;
+                }
+            }
+            if (startIndex == 0) {
+                // throw new InternalError("Factory " + factory + "not registered with service: " + this);
+                status = U_ILLEGAL_ARGUMENT_ERROR;
+                return NULL;
+            }
+            cacheResult = FALSE;
+        }
+
+        do {
+            currentDescriptor.remove();
+            key.currentDescriptor(currentDescriptor);
+            result = (CacheEntry*)serviceCache->get(currentDescriptor);
+            if (result != NULL) {
+                break;
+            }
+
+            // first test of cache failed, so we'll have to update
+            // the cache if we eventually succeed-- that is, if we're 
+            // going to update the cache at all.
+            putInCache = TRUE;
+
+            int32_t index = startIndex;
+            while (index < limit) {
+                ICUServiceFactory* f = (ICUServiceFactory*)factories->elementAt(index++);
+                UObject* service = f->create(key, this, status);
+                if (U_FAILURE(status)) {
+                    delete service;
+                    return NULL;
+                }
+                if (service != NULL) {
+                    result = new CacheEntry(currentDescriptor, service);
+                    if (result == NULL) {
+                        delete service;
+                        status = U_MEMORY_ALLOCATION_ERROR;
+                        return NULL;
+                    }
+
+                    goto outerEnd;
+                }
+            }
+
+            // prepare to load the cache with all additional ids that 
+            // will resolve to result, assuming we'll succeed.  We
+            // don't want to keep querying on an id that's going to
+            // fallback to the one that succeeded, we want to hit the
+            // cache the first time next goaround.
+            if (cacheDescriptorList._obj == NULL) {
+                cacheDescriptorList._obj = new UVector(uhash_deleteUnicodeString, NULL, 5, status);
+                if (U_FAILURE(status)) {
+                    return NULL;
+                }
+            }
+            UnicodeString* idToCache = new UnicodeString(currentDescriptor);
+            if (idToCache == NULL || idToCache->isBogus()) {
+                status = U_MEMORY_ALLOCATION_ERROR;
+                return NULL;
+            }
+
+            cacheDescriptorList._obj->addElement(idToCache, status);
+            if (U_FAILURE(status)) {
+                return NULL;
+            }
+        } while (key.fallback());
+outerEnd:
+
+        if (result != NULL) {
+            if (putInCache && cacheResult) {
+                serviceCache->put(result->actualDescriptor, result, status);
+                if (U_FAILURE(status)) {
+                    delete result;
+                    return NULL;
+                }
+
+                if (cacheDescriptorList._obj != NULL) {
+                    for (int32_t i = cacheDescriptorList._obj->size(); --i >= 0;) {
+                        UnicodeString* desc = (UnicodeString*)cacheDescriptorList._obj->elementAt(i);
+                        serviceCache->put(*desc, result, status);
+                        if (U_FAILURE(status)) {
+                            delete result;
+                            return NULL;
+                        }
+
+                        result->ref();
+                        cacheDescriptorList._obj->removeElementAt(i);
+                    }
+                }
+            }
+
+            if (actualReturn != NULL) {
+                // strip null prefix
+                if (result->actualDescriptor.indexOf((UChar)0x2f) == 0) { // U+002f=slash (/)
+                    actualReturn->remove();
+                    actualReturn->append(result->actualDescriptor, 
+                        1, 
+                        result->actualDescriptor.length() - 1);
+                } else {
+                    *actualReturn = result->actualDescriptor;
+                }
+
+                if (actualReturn->isBogus()) {
+                    status = U_MEMORY_ALLOCATION_ERROR;
+                    delete result;
+                    return NULL;
+                }
+            }
+
+            UObject* service = cloneInstance(result->service);
+            if (putInCache && !cacheResult) {
+                delete result;
+            }
+            return service;
+        }
+    }
+
+    return handleDefault(key, actualReturn, status);
+}
+
+UObject* 
+ICUService::handleDefault(const ICUServiceKey& /* key */, UnicodeString* /* actualIDReturn */, UErrorCode& /* status */) const 
+{
+    return NULL;
+}
+
+UVector& 
+ICUService::getVisibleIDs(UVector& result, UErrorCode& status) const {
+    return getVisibleIDs(result, NULL, status);
+}
+
+UVector& 
+ICUService::getVisibleIDs(UVector& result, const UnicodeString* matchID, UErrorCode& status) const 
+{
+    result.removeAllElements();
+
+    if (U_FAILURE(status)) {
+        return result;
+    }
+
+    ICUService * ncthis = (ICUService*)this; // cast away semantic const
+    {
+        Mutex mutex(&ncthis->lock);
+        const Hashtable* map = getVisibleIDMap(status);
+        if (map != NULL) {
+            ICUServiceKey* fallbackKey = createKey(matchID, status);
+
+            for (int32_t pos = -1;;) {
+                const UHashElement* e = map->nextElement(pos);
+                if (e == NULL) {
+                    break;
+                }
+
+                const UnicodeString* id = (const UnicodeString*)e->key.pointer;
+                if (fallbackKey != NULL) {
+                    if (!fallbackKey->isFallbackOf(*id)) {
+                        continue;
+                    }
+                }
+
+                UnicodeString* idClone = new UnicodeString(*id);
+                if (idClone == NULL || idClone->isBogus()) {
+                    delete idClone;
+                    status = U_MEMORY_ALLOCATION_ERROR;
+                    break;
+                }
+                result.addElement(idClone, status);
+                if (U_FAILURE(status)) {
+                    delete idClone;
+                    break;
+                }
+            }
+            delete fallbackKey;
+        }
+    }
+    if (U_FAILURE(status)) {
+        result.removeAllElements();
+    }
+    return result;
+}
+
+const Hashtable* 
+ICUService::getVisibleIDMap(UErrorCode& status) const {
+    if (U_FAILURE(status)) return NULL;
+
+    // must only be called when lock is already held
+
+    ICUService* ncthis = (ICUService*)this; // cast away semantic const
+    if (idCache == NULL) {
+        ncthis->idCache = new Hashtable(status);
+        if (idCache == NULL) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+        } else if (factories != NULL) {
+            for (int32_t pos = factories->size(); --pos >= 0;) {
+                ICUServiceFactory* f = (ICUServiceFactory*)factories->elementAt(pos);
+                f->updateVisibleIDs(*idCache, status);
+            }
+            if (U_FAILURE(status)) {
+                delete idCache;
+                ncthis->idCache = NULL;
+            }
+        }
+    }
+
+    return idCache;
+}
+
+
+UnicodeString& 
+ICUService::getDisplayName(const UnicodeString& id, UnicodeString& result) const 
+{
+    return getDisplayName(id, result, Locale::getDefault());
+}
+
+UnicodeString& 
+ICUService::getDisplayName(const UnicodeString& id, UnicodeString& result, const Locale& locale) const 
+{
+    {
+        ICUService* ncthis = (ICUService*)this; // cast away semantic const
+        UErrorCode status = U_ZERO_ERROR;
+        Mutex mutex(&ncthis->lock);
+        const Hashtable* map = getVisibleIDMap(status);
+        if (map != NULL) {
+            ICUServiceFactory* f = (ICUServiceFactory*)map->get(id);
+            if (f != NULL) {
+                f->getDisplayName(id, locale, result);
+                return result;
+            }
+
+            // fallback
+            UErrorCode status = U_ZERO_ERROR;
+            ICUServiceKey* fallbackKey = createKey(&id, status);
+            while (fallbackKey->fallback()) {
+                UnicodeString us;
+                fallbackKey->currentID(us);
+                f = (ICUServiceFactory*)map->get(us);
+                if (f != NULL) {
+                    f->getDisplayName(id, locale, result);
+                    delete fallbackKey;
+                    return result;
+                }
+            }
+            delete fallbackKey;
+        }
+    }
+    result.setToBogus();
+    return result;
+}
+
+UVector& 
+ICUService::getDisplayNames(UVector& result, UErrorCode& status) const 
+{
+    return getDisplayNames(result, Locale::getDefault(), NULL, status);
+}
+
+
+UVector& 
+ICUService::getDisplayNames(UVector& result, const Locale& locale, UErrorCode& status) const 
+{
+    return getDisplayNames(result, locale, NULL, status);
+}
+
+UVector& 
+ICUService::getDisplayNames(UVector& result, 
+                            const Locale& locale, 
+                            const UnicodeString* matchID, 
+                            UErrorCode& status) const 
+{
+    result.removeAllElements();
+    result.setDeleter(userv_deleteStringPair);
+    if (U_SUCCESS(status)) {
+        ICUService* ncthis = (ICUService*)this; // cast away semantic const
+        Mutex mutex(&ncthis->lock);
+
+        if (dnCache != NULL && dnCache->locale != locale) {
+            delete dnCache;
+            ncthis->dnCache = NULL;
+        }
+
+        if (dnCache == NULL) {
+            const Hashtable* m = getVisibleIDMap(status);
+            if (m != NULL) {
+                ncthis->dnCache = new DNCache(locale); 
+                if (dnCache == NULL) {
+                    status = U_MEMORY_ALLOCATION_ERROR;
+                    return result;
+                }
+
+                int32_t pos = -1;
+                const UHashElement* entry = NULL;
+                while ((entry = m->nextElement(pos)) != NULL) {
+                    const UnicodeString* id = (const UnicodeString*)entry->key.pointer;
+                    ICUServiceFactory* f = (ICUServiceFactory*)entry->value.pointer;
+                    UnicodeString dname;
+                    f->getDisplayName(*id, locale, dname);
+                    if (dname.isBogus()) {
+                        status = U_MEMORY_ALLOCATION_ERROR;
+                    } else {
+                        dnCache->cache.put(dname, (void*)id, status); // share pointer with visibleIDMap
+                        if (U_SUCCESS(status)) {
+                            continue;
+                        }
+                    }
+                    delete dnCache;
+                    ncthis->dnCache = NULL;
+                    return result;
+                }
+            }
+        }
+    }
+
+    ICUServiceKey* matchKey = createKey(matchID, status);
+    /* To ensure that all elements in the hashtable are iterated, set pos to -1.
+     * nextElement(pos) will skip the position at pos and begin the iteration
+     * at the next position, which in this case will be 0.
+     */
+    int32_t pos = -1; 
+    const UHashElement *entry = NULL;
+    while ((entry = dnCache->cache.nextElement(pos)) != NULL) {
+        const UnicodeString* id = (const UnicodeString*)entry->value.pointer;
+        if (matchKey != NULL && !matchKey->isFallbackOf(*id)) {
+            continue;
+        }
+        const UnicodeString* dn = (const UnicodeString*)entry->key.pointer;
+        StringPair* sp = StringPair::create(*id, *dn, status);
+        result.addElement(sp, status);
+        if (U_FAILURE(status)) {
+            result.removeAllElements();
+            break;
+        }
+    }
+    delete matchKey;
+
+    return result;
+}
+
+URegistryKey
+ICUService::registerInstance(UObject* objToAdopt, const UnicodeString& id, UErrorCode& status) 
+{
+    return registerInstance(objToAdopt, id, TRUE, status);
+}
+
+URegistryKey
+ICUService::registerInstance(UObject* objToAdopt, const UnicodeString& id, UBool visible, UErrorCode& status) 
+{
+    ICUServiceKey* key = createKey(&id, status);
+    if (key != NULL) {
+        UnicodeString canonicalID;
+        key->canonicalID(canonicalID);
+        delete key;
+
+        ICUServiceFactory* f = createSimpleFactory(objToAdopt, canonicalID, visible, status);
+        if (f != NULL) {
+            return registerFactory(f, status);
+        }
+    }
+    delete objToAdopt;
+    return NULL;
+}
+
+ICUServiceFactory* 
+ICUService::createSimpleFactory(UObject* objToAdopt, const UnicodeString& id, UBool visible, UErrorCode& status)
+{
+    if (U_SUCCESS(status)) {
+        if ((objToAdopt != NULL) && (!id.isBogus())) {
+            return new SimpleFactory(objToAdopt, id, visible);
+        }
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+    }
+    return NULL;
+}
+
+URegistryKey
+ICUService::registerFactory(ICUServiceFactory* factoryToAdopt, UErrorCode& status) 
+{
+    if (U_SUCCESS(status) && factoryToAdopt != NULL) {
+        Mutex mutex(&lock);
+
+        if (factories == NULL) {
+            factories = new UVector(deleteUObject, NULL, status);
+            if (U_FAILURE(status)) {
+                delete factories;
+                return NULL;
+            }
+        }
+        factories->insertElementAt(factoryToAdopt, 0, status);
+        if (U_SUCCESS(status)) {
+            clearCaches();
+        } else {
+            delete factoryToAdopt;
+            factoryToAdopt = NULL;
+        }
+    }
+
+    if (factoryToAdopt != NULL) {
+        notifyChanged();
+    }
+
+    return (URegistryKey)factoryToAdopt;
+}
+
+UBool 
+ICUService::unregister(URegistryKey rkey, UErrorCode& status) 
+{
+    ICUServiceFactory *factory = (ICUServiceFactory*)rkey;
+    UBool result = FALSE;
+    if (factory != NULL && factories != NULL) {
+        Mutex mutex(&lock);
+
+        if (factories->removeElement(factory)) {
+            clearCaches();
+            result = TRUE;
+        } else {
+            status = U_ILLEGAL_ARGUMENT_ERROR;
+            delete factory;
+        }
+    }
+    if (result) {
+        notifyChanged();
+    }
+    return result;
+}
+
+void 
+ICUService::reset() 
+{
+    {
+        Mutex mutex(&lock);
+        reInitializeFactories();
+        clearCaches();
+    }
+    notifyChanged();
+}
+
+void 
+ICUService::reInitializeFactories() 
+{
+    if (factories != NULL) {
+        factories->removeAllElements();
+    }
+}
+
+UBool 
+ICUService::isDefault() const 
+{
+    return countFactories() == 0;
+}
+
+ICUServiceKey* 
+ICUService::createKey(const UnicodeString* id, UErrorCode& status) const 
+{
+    return (U_FAILURE(status) || id == NULL) ? NULL : new ICUServiceKey(*id);
+}
+
+void 
+ICUService::clearCaches() 
+{
+    // callers synchronize before use
+    ++timestamp;
+    delete dnCache;
+    dnCache = NULL;
+    delete idCache;
+    idCache = NULL;
+    delete serviceCache; serviceCache = NULL;
+}
+
+void 
+ICUService::clearServiceCache() 
+{
+    // callers synchronize before use
+    delete serviceCache; serviceCache = NULL;
+}
+
+UBool 
+ICUService::acceptsListener(const EventListener& l) const 
+{
+    return l.getDynamicClassID() == ServiceListener::getStaticClassID();
+}
+
+void 
+ICUService::notifyListener(EventListener& l) const 
+{
+    ((ServiceListener&)l).serviceChanged(*this);
+}
+
+UnicodeString&
+ICUService::getName(UnicodeString& result) const 
+{
+    return result.append(name);
+}
+
+int32_t 
+ICUService::countFactories() const 
+{
+    return factories == NULL ? 0 : factories->size();
+}
+
+int32_t
+ICUService::getTimestamp() const
+{
+    return timestamp;
+}
+
+U_NAMESPACE_END
+
+/* UCONFIG_NO_SERVICE */
+#endif
diff --git a/icu/source/common/serv.h b/icu/source/common/serv.h
new file mode 100644
index 0000000..2e498fb
--- /dev/null
+++ b/icu/source/common/serv.h
@@ -0,0 +1,996 @@
+/**
+ *******************************************************************************
+ * Copyright (C) 2001-2007, International Business Machines Corporation.       *
+ * All Rights Reserved.                                                        *
+ *******************************************************************************
+ */
+
+#ifndef ICUSERV_H
+#define ICUSERV_H
+
+#include "unicode/utypes.h"
+
+#if UCONFIG_NO_SERVICE
+
+U_NAMESPACE_BEGIN
+
+/*
+ * Allow the declaration of APIs with pointers to ICUService
+ * even when service is removed from the build.
+ */
+class ICUService;
+
+U_NAMESPACE_END
+
+#else
+
+#include "unicode/unistr.h"
+#include "unicode/locid.h"
+#include "unicode/umisc.h"
+
+#include "hash.h"
+#include "uvector.h"
+#include "servnotf.h"
+
+class ICUServiceTest;
+
+U_NAMESPACE_BEGIN
+
+class ICUServiceKey;
+class ICUServiceFactory;
+class SimpleFactory;
+class ServiceListener;
+class ICUService;
+
+class DNCache;
+
+/*******************************************************************
+ * ICUServiceKey
+ */
+
+/**
+ * <p>ICUServiceKeys are used to communicate with factories to
+ * generate an instance of the service.  ICUServiceKeys define how
+ * ids are canonicalized, provide both a current id and a current
+ * descriptor to use in querying the cache and factories, and
+ * determine the fallback strategy.</p>
+ *
+ * <p>ICUServiceKeys provide both a currentDescriptor and a currentID.
+ * The descriptor contains an optional prefix, followed by '/'
+ * and the currentID.  Factories that handle complex keys,
+ * for example number format factories that generate multiple
+ * kinds of formatters for the same locale, use the descriptor 
+ * to provide a fully unique identifier for the service object, 
+ * while using the currentID (in this case, the locale string),
+ * as the visible IDs that can be localized.</p>
+ *
+ * <p>The default implementation of ICUServiceKey has no fallbacks and
+ * has no custom descriptors.</p> 
+ */
+class U_COMMON_API ICUServiceKey : public UObject {
+ private: 
+  const UnicodeString _id;
+
+ protected:
+  static const UChar PREFIX_DELIMITER;
+
+ public:
+
+  /**
+   * <p>Construct a key from an id.</p>
+   *
+   * @param id the ID from which to construct the key.
+   */
+  ICUServiceKey(const UnicodeString& id);
+
+  /**
+   * <p>Virtual destructor.</p>
+   */
+  virtual ~ICUServiceKey();
+
+ /**
+  * <p>Return the original ID used to construct this key.</p>
+  *
+  * @return the ID used to construct this key.
+  */
+  virtual const UnicodeString& getID() const;
+
+ /**
+  * <p>Return the canonical version of the original ID.  This implementation
+  * appends the original ID to result.  Result is returned as a convenience.</p>
+  *
+  * @param result the output parameter to which the id will be appended.
+  * @return the modified result.
+  */
+  virtual UnicodeString& canonicalID(UnicodeString& result) const;
+
+ /**
+  * <p>Return the (canonical) current ID.  This implementation appends
+  * the canonical ID to result.  Result is returned as a convenience.</p>
+  *
+  * @param result the output parameter to which the current id will be appended.
+  * @return the modified result.  
+  */
+  virtual UnicodeString& currentID(UnicodeString& result) const;
+
+ /**
+  * <p>Return the current descriptor.  This implementation appends
+  * the current descriptor to result.  Result is returned as a convenience.</p>
+  *
+  * <p>The current descriptor is used to fully
+  * identify an instance of the service in the cache.  A
+  * factory may handle all descriptors for an ID, or just a
+  * particular descriptor.  The factory can either parse the
+  * descriptor or use custom API on the key in order to
+  * instantiate the service.</p>
+  *
+  * @param result the output parameter to which the current id will be appended.
+  * @return the modified result.  
+  */
+  virtual UnicodeString& currentDescriptor(UnicodeString& result) const;
+
+ /**
+  * <p>If the key has a fallback, modify the key and return true,
+  * otherwise return false.  The current ID will change if there
+  * is a fallback.  No currentIDs should be repeated, and fallback
+  * must eventually return false.  This implementation has no fallbacks
+  * and always returns false.</p>
+  *
+  * @return TRUE if the ICUServiceKey changed to a valid fallback value.
+  */
+  virtual UBool fallback();
+
+ /**
+  * <p>Return TRUE if a key created from id matches, or would eventually
+  * fallback to match, the canonical ID of this ICUServiceKey.</p>
+  *
+  * @param id the id to test.
+  * @return TRUE if this ICUServiceKey's canonical ID is a fallback of id.
+  */
+  virtual UBool isFallbackOf(const UnicodeString& id) const;
+
+ /**
+  * <p>Return the prefix.  This implementation leaves result unchanged.
+  * Result is returned as a convenience.</p>
+  *
+  * @param result the output parameter to which the prefix will be appended.
+  * @return the modified result.
+  */
+  virtual UnicodeString& prefix(UnicodeString& result) const;
+
+ /**
+  * <p>A utility to parse the prefix out of a descriptor string.  Only
+  * the (undelimited) prefix, if any, remains in result.  Result is returned as a 
+  * convenience.</p>
+  *
+  * @param result an input/output parameter that on entry is a descriptor, and 
+  * on exit is the prefix of that descriptor.
+  * @return the modified result.
+  */
+  static UnicodeString& parsePrefix(UnicodeString& result);
+
+  /**
+  * <p>A utility to parse the suffix out of a descriptor string.  Only
+  * the (undelimited) suffix, if any, remains in result.  Result is returned as a 
+  * convenience.</p>
+  *
+  * @param result an input/output parameter that on entry is a descriptor, and 
+  * on exit is the suffix of that descriptor.
+  * @return the modified result.
+  */
+  static UnicodeString& parseSuffix(UnicodeString& result);
+
+public:
+  /**
+   * UObject RTTI boilerplate.
+   */
+  static UClassID U_EXPORT2 getStaticClassID();
+
+  /**
+   * UObject RTTI boilerplate.
+   */
+  virtual UClassID getDynamicClassID() const;
+
+#ifdef SERVICE_DEBUG
+ public:
+  virtual UnicodeString& debug(UnicodeString& result) const;
+  virtual UnicodeString& debugClass(UnicodeString& result) const;
+#endif
+
+};
+
+ /*******************************************************************
+  * ICUServiceFactory
+  */
+
+ /**
+  * <p>An implementing ICUServiceFactory generates the service objects maintained by the
+  * service.  A factory generates a service object from a key,
+  * updates id->factory mappings, and returns the display name for
+  * a supported id.</p>
+  */
+class U_COMMON_API ICUServiceFactory : public UObject {
+ public:
+
+    /**
+     * <p>Create a service object from the key, if this factory
+     * supports the key.  Otherwise, return NULL.</p>
+     *
+     * <p>If the factory supports the key, then it can call
+     * the service's getKey(ICUServiceKey, String[], ICUServiceFactory) method
+     * passing itself as the factory to get the object that
+     * the service would have created prior to the factory's
+     * registration with the service.  This can change the
+     * key, so any information required from the key should
+     * be extracted before making such a callback.</p>
+     *
+     * @param key the service key.
+     * @param service the service with which this factory is registered.
+     * @param status the error code status.
+     * @return the service object, or NULL if the factory does not support the key.
+     */
+    virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const = 0;
+
+    /**
+     * <p>Update result to reflect the IDs (not descriptors) that this
+     * factory publicly handles.  Result contains mappings from ID to
+     * factory.  On entry it will contain all (visible) mappings from
+     * previously-registered factories.</p>
+     *
+     * <p>This function, together with getDisplayName, are used to
+     * support ICUService::getDisplayNames.  The factory determines
+     * which IDs (of those it supports) it will make visible, and of
+     * those, which it will provide localized display names for.  In
+     * most cases it will register mappings from all IDs it supports
+     * to itself.</p>
+     *
+     * @param result the mapping table to update.
+     * @param status the error code status.
+     */
+    virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const = 0;
+
+    /**
+     * <p>Return, in result, the display name of the id in the provided locale.
+     * This is an id, not a descriptor.  If the id is 
+     * not visible, sets result to bogus.  If the
+     * incoming result is bogus, it remains bogus.  Result is returned as a
+     * convenience.  Results are not defined if id is not one supported by this
+         * factory.</p>
+     *
+     * @param id a visible id supported by this factory.
+     * @param locale the locale for which to generate the corresponding localized display name.
+     * @param result output parameter to hold the display name.
+     * @return result.
+     */
+    virtual UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const = 0;
+};
+
+/*
+ ******************************************************************
+ */
+
+ /**
+  * <p>A default implementation of factory.  This provides default
+  * implementations for subclasses, and implements a singleton
+  * factory that matches a single ID and returns a single
+  * (possibly deferred-initialized) instance.  This implements
+  * updateVisibleIDs to add a mapping from its ID to itself
+  * if visible is true, or to remove any existing mapping
+  * for its ID if visible is false.  No localization of display
+  * names is performed.</p>
+  */
+class U_COMMON_API SimpleFactory : public ICUServiceFactory {
+ protected:
+  UObject* _instance;
+  const UnicodeString _id;
+  const UBool _visible;
+
+ public:
+  /**
+   * <p>Construct a SimpleFactory that maps a single ID to a single 
+   * service instance.  If visible is TRUE, the ID will be visible.
+   * The instance must not be NULL.  The SimpleFactory will adopt
+   * the instance, which must not be changed subsequent to this call.</p>
+   *
+   * @param instanceToAdopt the service instance to adopt.
+   * @param id the ID to assign to this service instance.
+   * @param visible if TRUE, the ID will be visible.
+   */
+  SimpleFactory(UObject* instanceToAdopt, const UnicodeString& id, UBool visible = TRUE);
+
+  /**
+   * <p>Destructor.</p>
+   */
+  virtual ~SimpleFactory();
+
+  /**
+   * <p>This implementation returns a clone of the service instance if the factory's ID is equal to
+   * the key's currentID.  Service and prefix are ignored.</p>
+   *
+   * @param key the service key.
+   * @param service the service with which this factory is registered.
+   * @param status the error code status.
+   * @return the service object, or NULL if the factory does not support the key.
+   */
+  virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const;
+
+  /**
+   * <p>This implementation adds a mapping from ID -> this to result if visible is TRUE, 
+   * otherwise it removes ID from result.</p>
+   *
+   * @param result the mapping table to update.
+   * @param status the error code status.
+   */
+  virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const;
+
+  /**
+   * <p>This implementation returns the factory ID if it equals id and visible is TRUE,
+   * otherwise it returns the empty string.  (This implementation provides
+   * no localized id information.)</p>
+   *
+   * @param id a visible id supported by this factory.
+   * @param locale the locale for which to generate the corresponding localized display name.
+   * @param result output parameter to hold the display name.
+   * @return result.
+   */
+  virtual UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const;
+
+public:
+ /**
+  * UObject RTTI boilerplate.
+  */
+  static UClassID U_EXPORT2 getStaticClassID();
+
+ /**
+  * UObject RTTI boilerplate.
+  */
+  virtual UClassID getDynamicClassID() const;
+
+#ifdef SERVICE_DEBUG
+ public:
+  virtual UnicodeString& debug(UnicodeString& toAppendTo) const;
+  virtual UnicodeString& debugClass(UnicodeString& toAppendTo) const;
+#endif
+
+};
+
+/*
+ ******************************************************************
+ */
+
+/**
+ * <p>ServiceListener is the listener that ICUService provides by default.
+ * ICUService will notifiy this listener when factories are added to
+ * or removed from the service.  Subclasses can provide
+ * different listener interfaces that extend EventListener, and modify
+ * acceptsListener and notifyListener as appropriate.</p>
+ */
+class U_COMMON_API ServiceListener : public EventListener {
+public:
+    /**
+     * <p>This method is called when the service changes. At the time of the
+     * call this listener is registered with the service.  It must
+     * not modify the notifier in the context of this call.</p>
+     * 
+     * @param service the service that changed.
+     */
+    virtual void serviceChanged(const ICUService& service) const = 0;
+    
+public:
+    /**
+     * UObject RTTI boilerplate.
+     */
+    static UClassID U_EXPORT2 getStaticClassID();
+    
+    /**
+     * UObject RTTI boilerplate.
+     */
+    virtual UClassID getDynamicClassID() const;
+    
+};
+
+/*
+ ******************************************************************
+ */
+
+/**
+ * <p>A StringPair holds a displayName/ID pair.  ICUService uses it
+ * as the array elements returned by getDisplayNames.
+ */
+class U_COMMON_API StringPair : public UMemory {
+public:
+  /**
+   * <p>The display name of the pair.</p>
+   */
+  const UnicodeString displayName;
+
+  /**
+   * <p>The ID of the pair.</p>
+   */
+  const UnicodeString id;
+
+  /**
+   * <p>Creates a string pair from a displayName and an ID.</p>
+   *
+   * @param displayName the displayName.
+   * @param id the ID.
+   * @param status the error code status.
+   * @return a StringPair if the creation was successful, otherwise NULL.
+   */
+  static StringPair* create(const UnicodeString& displayName, 
+                            const UnicodeString& id,
+                            UErrorCode& status);
+
+  /**
+   * <p>Return TRUE if either string of the pair is bogus.</p>
+   * @return TRUE if either string of the pair is bogus.
+   */
+  UBool isBogus() const;
+
+private:
+  StringPair(const UnicodeString& displayName, const UnicodeString& id);
+};
+
+/*******************************************************************
+ * ICUService
+ */
+
+ /**
+ * <p>A Service provides access to service objects that implement a
+ * particular service, e.g. transliterators.  Users provide a String
+ * id (for example, a locale string) to the service, and get back an
+ * object for that id.  Service objects can be any kind of object.  A
+ * new service object is returned for each query. The caller is
+ * responsible for deleting it.</p>
+ *
+ * <p>Services 'canonicalize' the query ID and use the canonical ID to
+ * query for the service.  The service also defines a mechanism to
+ * 'fallback' the ID multiple times.  Clients can optionally request
+ * the actual ID that was matched by a query when they use an ID to
+ * retrieve a service object.</p>
+ *
+ * <p>Service objects are instantiated by ICUServiceFactory objects
+ * registered with the service.  The service queries each
+ * ICUServiceFactory in turn, from most recently registered to
+ * earliest registered, until one returns a service object.  If none
+ * responds with a service object, a fallback ID is generated, and the
+ * process repeats until a service object is returned or until the ID
+ * has no further fallbacks.</p>
+ *
+ * <p>In ICU 2.4, UObject (the base class of service instances) does
+ * not define a polymorphic clone function.  ICUService uses clones to
+ * manage ownership.  Thus, for now, ICUService defines an abstract
+ * method, cloneInstance, that clients must implement to create clones
+ * of the service instances.  This may change in future releases of
+ * ICU.</p>
+ *
+ * <p>ICUServiceFactories can be dynamically registered and
+ * unregistered with the service.  When registered, an
+ * ICUServiceFactory is installed at the head of the factory list, and
+ * so gets 'first crack' at any keys or fallback keys.  When
+ * unregistered, it is removed from the service and can no longer be
+ * located through it.  Service objects generated by this factory and
+ * held by the client are unaffected.</p>
+ *
+ * <p>If a service has variants (e.g., the different variants of
+ * BreakIterator) an ICUServiceFactory can use the prefix of the
+ * ICUServiceKey to determine the variant of a service to generate.
+ * If it does not support all variants, it can request
+ * previously-registered factories to handle the ones it does not
+ * support.</p>
+ *
+ * <p>ICUService uses ICUServiceKeys to query factories and perform
+ * fallback.  The ICUServiceKey defines the canonical form of the ID,
+ * and implements the fallback strategy.  Custom ICUServiceKeys can be
+ * defined that parse complex IDs into components that
+ * ICUServiceFactories can more easily use.  The ICUServiceKey can
+ * cache the results of this parsing to save repeated effort.
+ * ICUService provides convenience APIs that take UnicodeStrings and
+ * generate default ICUServiceKeys for use in querying.</p>
+ *
+ * <p>ICUService provides API to get the list of IDs publicly
+ * supported by the service (although queries aren't restricted to
+ * this list).  This list contains only 'simple' IDs, and not fully
+ * unique IDs.  ICUServiceFactories are associated with each simple ID
+ * and the responsible factory can also return a human-readable
+ * localized version of the simple ID, for use in user interfaces.
+ * ICUService can also provide an array of the all the localized
+ * visible IDs and their corresponding internal IDs.</p>
+ *
+ * <p>ICUService implements ICUNotifier, so that clients can register
+ * to receive notification when factories are added or removed from
+ * the service.  ICUService provides a default EventListener
+ * subinterface, ServiceListener, which can be registered with the
+ * service.  When the service changes, the ServiceListener's
+ * serviceChanged method is called with the service as the
+ * argument.</p>
+ *
+ * <p>The ICUService API is both rich and generic, and it is expected
+ * that most implementations will statically 'wrap' ICUService to
+ * present a more appropriate API-- for example, to declare the type
+ * of the objects returned from get, to limit the factories that can
+ * be registered with the service, or to define their own listener
+ * interface with a custom callback method.  They might also customize
+ * ICUService by overriding it, for example, to customize the
+ * ICUServiceKey and fallback strategy.  ICULocaleService is a
+ * subclass of ICUService that uses Locale names as IDs and uses
+ * ICUServiceKeys that implement the standard resource bundle fallback
+ * strategy.  Most clients will wish to subclass it instead of
+ * ICUService.</p> 
+ */
+class U_COMMON_API ICUService : public ICUNotifier {
+ protected: 
+    /**
+     * Name useful for debugging.
+     */
+    const UnicodeString name;
+
+ private:
+
+    /**
+     * single lock used by this service.
+     */
+    UMTX lock;
+
+    /**
+     * Timestamp so iterators can be fail-fast.
+     */
+    uint32_t timestamp;
+
+    /**
+     * All the factories registered with this service.
+     */
+    UVector* factories;
+
+    /**
+     * The service cache.
+     */
+    Hashtable* serviceCache;
+
+    /**
+     * The ID cache.
+     */
+    Hashtable* idCache;
+
+    /**
+     * The name cache.
+     */
+    DNCache* dnCache;
+
+    /**
+     * Constructor.
+     */
+ public:
+    /**
+     * <p>Construct a new ICUService.</p>
+     */
+    ICUService();
+
+    /**
+     * <p>Construct with a name (useful for debugging).</p>
+     *
+     * @param name a name to use in debugging.
+     */
+    ICUService(const UnicodeString& name);
+
+    /**
+     * <p>Destructor.</p>
+     */
+    virtual ~ICUService();
+
+    /**
+     * <p>Return the name of this service. This will be the empty string if none was assigned.
+     * Returns result as a convenience.</p>
+     *
+     * @param result an output parameter to contain the name of this service.
+     * @return the name of this service.
+     */
+    UnicodeString& getName(UnicodeString& result) const;
+
+    /**
+     * <p>Convenience override for get(ICUServiceKey&, UnicodeString*). This uses
+     * createKey to create a key for the provided descriptor.</p>
+     *
+     * @param descriptor the descriptor.
+     * @param status the error code status.
+     * @return the service instance, or NULL.
+     */
+    UObject* get(const UnicodeString& descriptor, UErrorCode& status) const;
+
+    /**
+     * <p>Convenience override for get(ICUServiceKey&, UnicodeString*).  This uses
+     * createKey to create a key from the provided descriptor.</p>
+     *
+     * @param descriptor the descriptor.
+     * @param actualReturn a pointer to a UnicodeString to hold the matched descriptor, or NULL.
+     * @param status the error code status.
+     * @return the service instance, or NULL.
+     */
+    UObject* get(const UnicodeString& descriptor, UnicodeString* actualReturn, UErrorCode& status) const;
+
+    /**
+     * <p>Convenience override for get(ICUServiceKey&, UnicodeString*).</p>
+     *
+     * @param key the key.
+     * @param status the error code status.
+     * @return the service instance, or NULL.
+     */
+    UObject* getKey(ICUServiceKey& key, UErrorCode& status) const;
+
+    /**
+     * <p>Given a key, return a service object, and, if actualReturn
+     * is not NULL, the descriptor with which it was found in the
+     * first element of actualReturn.  If no service object matches
+     * this key, returns NULL and leaves actualReturn unchanged.</p>
+     *
+     * <p>This queries the cache using the key's descriptor, and if no
+     * object in the cache matches, tries the key on each
+     * registered factory, in order.  If none generates a service
+     * object for the key, repeats the process with each fallback of
+     * the key, until either a factory returns a service object, or the key
+     * has no fallback.  If no object is found, the result of handleDefault
+     * is returned.</p>
+     *
+     * <p>Subclasses can override this method to further customize the 
+     * result before returning it.
+     *
+     * @param key the key.
+     * @param actualReturn a pointer to a UnicodeString to hold the matched descriptor, or NULL.
+     * @param status the error code status.
+     * @return the service instance, or NULL.
+     */
+    virtual UObject* getKey(ICUServiceKey& key, UnicodeString* actualReturn, UErrorCode& status) const;
+
+    /**
+     * <p>This version of getKey is only called by ICUServiceFactories within the scope
+     * of a previous getKey call, to determine what previously-registered factories would
+     * have returned.  For details, see getKey(ICUServiceKey&, UErrorCode&).  Subclasses
+     * should not call it directly, but call through one of the other get functions.</p>
+     * 
+     * @param key the key.
+     * @param actualReturn a pointer to a UnicodeString to hold the matched descriptor, or NULL.
+     * @param factory the factory making the recursive call.
+     * @param status the error code status.
+     * @return the service instance, or NULL.
+     */
+    UObject* getKey(ICUServiceKey& key, UnicodeString* actualReturn, const ICUServiceFactory* factory, UErrorCode& status) const;
+
+    /**
+     * <p>Convenience override for getVisibleIDs(String) that passes null
+     * as the fallback, thus returning all visible IDs.</p>
+     *
+     * @param result a vector to hold the returned IDs.
+     * @param status the error code status.
+     * @return the result vector.
+     */
+    UVector& getVisibleIDs(UVector& result, UErrorCode& status) const;
+
+    /**
+     * <p>Return a snapshot of the visible IDs for this service.  This
+     * list will not change as ICUServiceFactories are added or removed, but the
+     * supported IDs will, so there is no guarantee that all and only
+     * the IDs in the returned list will be visible and supported by the
+     * service in subsequent calls.</p>
+     *
+     * <p>The IDs are returned as pointers to UnicodeStrings.  The
+     * caller owns the IDs.  Previous contents of result are discarded before
+     * new elements, if any, are added.</p>
+     *
+     * <p>matchID is passed to createKey to create a key.  If the key
+     * is not NULL, its isFallbackOf method is used to filter out IDs
+     * that don't match the key or have it as a fallback.</p>
+     *
+     * @param result a vector to hold the returned IDs.
+     * @param matchID an ID used to filter the result, or NULL if all IDs are desired.
+     * @param status the error code status.
+     * @return the result vector.
+     */
+    UVector& getVisibleIDs(UVector& result, const UnicodeString* matchID, UErrorCode& status) const;
+
+    /**
+     * <p>Convenience override for getDisplayName(const UnicodeString&, const Locale&, UnicodeString&) that
+     * uses the current default locale.</p>
+     *
+     * @param id the ID for which to retrieve the localized displayName.
+     * @param result an output parameter to hold the display name.
+     * @return the modified result.
+     */
+    UnicodeString& getDisplayName(const UnicodeString& id, UnicodeString& result) const;
+
+    /**
+     * <p>Given a visible ID, return the display name in the requested locale.
+     * If there is no directly supported ID corresponding to this ID, result is
+     * set to bogus.</p>
+     *
+     * @param id the ID for which to retrieve the localized displayName.
+     * @param result an output parameter to hold the display name.
+     * @param locale the locale in which to localize the ID.
+     * @return the modified result.
+     */
+    UnicodeString& getDisplayName(const UnicodeString& id, UnicodeString& result, const Locale& locale) const;
+
+    /**
+     * <p>Convenience override of getDisplayNames(const Locale&, const UnicodeString*) that 
+     * uses the current default Locale as the locale and NULL for
+     * the matchID.</p>
+     *
+     * @param result a vector to hold the returned displayName/id StringPairs.
+     * @param status the error code status.
+     * @return the modified result vector.
+     */
+    UVector& getDisplayNames(UVector& result, UErrorCode& status) const;
+
+    /**
+     * <p>Convenience override of getDisplayNames(const Locale&, const UnicodeString*) that 
+     * uses NULL for the matchID.</p>
+     *
+     * @param result a vector to hold the returned displayName/id StringPairs.
+     * @param locale the locale in which to localize the ID.
+     * @param status the error code status.
+     * @return the modified result vector.
+     */
+    UVector& getDisplayNames(UVector& result, const Locale& locale, UErrorCode& status) const;
+
+    /**
+     * <p>Return a snapshot of the mapping from display names to visible
+     * IDs for this service.  This set will not change as factories
+     * are added or removed, but the supported IDs will, so there is
+     * no guarantee that all and only the IDs in the returned map will
+     * be visible and supported by the service in subsequent calls,
+     * nor is there any guarantee that the current display names match
+     * those in the result.</p>
+     *
+     * <p>The names are returned as pointers to StringPairs, which
+     * contain both the displayName and the corresponding ID.  The
+     * caller owns the StringPairs.  Previous contents of result are
+     * discarded before new elements, if any, are added.</p>
+     *
+     * <p>matchID is passed to createKey to create a key.  If the key
+     * is not NULL, its isFallbackOf method is used to filter out IDs
+     * that don't match the key or have it as a fallback.</p>
+     *
+     * @param result a vector to hold the returned displayName/id StringPairs.
+     * @param locale the locale in which to localize the ID.
+     * @param matchID an ID used to filter the result, or NULL if all IDs are desired.
+     * @param status the error code status.
+     * @return the result vector.  */
+    UVector& getDisplayNames(UVector& result,
+                             const Locale& locale, 
+                             const UnicodeString* matchID, 
+                             UErrorCode& status) const;
+
+    /**
+     * <p>A convenience override of registerInstance(UObject*, const UnicodeString&, UBool)
+     * that defaults visible to TRUE.</p>
+     *
+     * @param objToAdopt the object to register and adopt.
+     * @param id the ID to assign to this object.
+     * @param status the error code status.
+     * @return a registry key that can be passed to unregister to unregister
+     * (and discard) this instance.
+     */
+    URegistryKey registerInstance(UObject* objToAdopt, const UnicodeString& id, UErrorCode& status);
+
+    /**
+     * <p>Register a service instance with the provided ID.  The ID will be 
+     * canonicalized.  The canonicalized ID will be returned by
+     * getVisibleIDs if visible is TRUE.  The service instance will be adopted and
+     * must not be modified subsequent to this call.</p>
+     *
+     * <p>This issues a serviceChanged notification to registered listeners.</p>
+     *
+     * <p>This implementation wraps the object using
+     * createSimpleFactory, and calls registerFactory.</p>
+     *
+     * @param objToAdopt the object to register and adopt.
+     * @param id the ID to assign to this object.
+     * @param visible TRUE if getVisibleIDs is to return this ID.
+     * @param status the error code status.
+     * @return a registry key that can be passed to unregister() to unregister
+     * (and discard) this instance.
+     */
+    virtual URegistryKey registerInstance(UObject* objToAdopt, const UnicodeString& id, UBool visible, UErrorCode& status);
+
+    /**
+     * <p>Register an ICUServiceFactory.  Returns a registry key that
+     * can be used to unregister the factory.  The factory
+     * must not be modified subsequent to this call.  The service owns
+     * all registered factories. In case of an error, the factory is
+     * deleted.</p>
+     *
+     * <p>This issues a serviceChanged notification to registered listeners.</p>
+     *
+     * <p>The default implementation accepts all factories.</p>
+     *
+     * @param factoryToAdopt the factory to register and adopt.
+     * @param status the error code status.
+     * @return a registry key that can be passed to unregister to unregister
+     * (and discard) this factory.
+     */
+    virtual URegistryKey registerFactory(ICUServiceFactory* factoryToAdopt, UErrorCode& status);
+
+    /**
+     * <p>Unregister a factory using a registry key returned by
+     * registerInstance or registerFactory.  After a successful call,
+     * the factory will be removed from the service factory list and
+     * deleted, and the key becomes invalid.</p>
+     *
+     * <p>This issues a serviceChanged notification to registered
+     * listeners.</p>
+     *
+     * @param rkey the registry key.
+     * @param status the error code status.  
+     * @return TRUE if the call successfully unregistered the factory.
+     */
+    virtual UBool unregister(URegistryKey rkey, UErrorCode& status);
+
+    /**
+     * </p>Reset the service to the default factories.  The factory
+     * lock is acquired and then reInitializeFactories is called.</p>
+     *
+     * <p>This issues a serviceChanged notification to registered listeners.</p>
+     */
+    virtual void reset(void);
+
+    /**
+     * <p>Return TRUE if the service is in its default state.</p>
+     *
+     * <p>The default implementation returns TRUE if there are no 
+     * factories registered.</p>
+     */
+    virtual UBool isDefault(void) const;
+
+    /**
+     * <p>Create a key from an ID.  If ID is NULL, returns NULL.</p>
+     *
+     * <p>The default implementation creates an ICUServiceKey instance.
+     * Subclasses can override to define more useful keys appropriate
+     * to the factories they accept.</p>
+     *
+     * @param a pointer to the ID for which to create a default ICUServiceKey.
+     * @param status the error code status.
+     * @return the ICUServiceKey corresponding to ID, or NULL.
+     */
+    virtual ICUServiceKey* createKey(const UnicodeString* id, UErrorCode& status) const;
+
+    /**
+     * <p>Clone object so that caller can own the copy.  In ICU2.4, UObject doesn't define
+     * clone, so we need an instance-aware method that knows how to do this.
+     * This is public so factories can call it, but should really be protected.</p>
+     *
+     * @param instance the service instance to clone.
+     * @return a clone of the passed-in instance, or NULL if cloning was unsuccessful.
+     */
+    virtual UObject* cloneInstance(UObject* instance) const = 0;
+
+
+    /************************************************************************
+     * Subclassing API
+     */
+
+ protected:
+
+    /**
+     * <p>Create a factory that wraps a single service object.  Called by registerInstance.</p>
+     *
+     * <p>The default implementation returns an instance of SimpleFactory.</p>
+     *
+     * @param instanceToAdopt the service instance to adopt.
+     * @param id the ID to assign to this service instance.
+     * @param visible if TRUE, the ID will be visible.
+     * @param status the error code status.
+     * @return an instance of ICUServiceFactory that maps this instance to the provided ID.
+     */
+    virtual ICUServiceFactory* createSimpleFactory(UObject* instanceToAdopt, const UnicodeString& id, UBool visible, UErrorCode& status);
+
+    /**
+     * <p>Reinitialize the factory list to its default state.  After this call, isDefault()
+     * must return TRUE.</p>
+     *
+     * <p>This issues a serviceChanged notification to registered listeners.</p>
+     *
+     * <p>The default implementation clears the factory list.
+     * Subclasses can override to provide other default initialization
+     * of the factory list.  Subclasses must not call this method
+     * directly, since it must only be called while holding write
+     * access to the factory list.</p>
+     */
+    virtual void reInitializeFactories(void);
+
+    /**
+     * <p>Default handler for this service if no factory in the factory list
+     * handled the key passed to getKey.</p>
+     *
+     * <p>The default implementation returns NULL.</p>
+     *
+     * @param key the key.
+     * @param actualReturn a pointer to a UnicodeString to hold the matched descriptor, or NULL.
+     * @param status the error code status.
+     * @return the service instance, or NULL.
+     */
+    virtual UObject* handleDefault(const ICUServiceKey& key, UnicodeString* actualReturn, UErrorCode& status) const;
+
+    /**
+     * <p>Clear caches maintained by this service.</p>
+     *
+     * <p>Subclasses can override if they implement additional caches
+     * that need to be cleared when the service changes.  Subclasses
+     * should generally not call this method directly, as it must only
+     * be called while synchronized on the factory lock.</p>
+     */
+    virtual void clearCaches(void);
+
+    /**
+     * <p>Return true if the listener is accepted.</p>
+     *
+     * <p>The default implementation accepts the listener if it is
+     * a ServiceListener.  Subclasses can override this to accept
+     * different listeners.</p>
+     *
+     * @param l the listener to test.
+     * @return TRUE if the service accepts the listener.
+     */
+    virtual UBool acceptsListener(const EventListener& l) const;
+
+    /**
+     * <p>Notify the listener of a service change.</p>
+     *
+     * <p>The default implementation assumes a ServiceListener.
+     * If acceptsListener has been overridden to accept different
+     * listeners, this should be overridden as well.</p>
+     *
+     * @param l the listener to notify.
+     */
+    virtual void notifyListener(EventListener& l) const;
+
+    /************************************************************************
+     * Utilities for subclasses.
+     */
+
+    /**
+     * <p>Clear only the service cache.</p>
+     *
+     * <p>This can be called by subclasses when a change affects the service
+     * cache but not the ID caches, e.g., when the default locale changes
+     * the resolution of IDs also changes, requiring the cache to be
+     * flushed, but not the visible IDs themselves.</p>
+     */
+    void clearServiceCache(void);
+
+    /**
+     * <p>Return a map from visible IDs to factories.
+     * This must only be called when the mutex is held.</p>
+     *
+     * @param status the error code status.
+     * @return a Hashtable containing mappings from visible
+     * IDs to factories.
+     */
+    const Hashtable* getVisibleIDMap(UErrorCode& status) const;
+
+    /**
+     * <p>Allow subclasses to read the time stamp.</p>
+     *
+     * @return the timestamp.
+     */
+    int32_t getTimestamp(void) const;
+
+    /**
+     * <p>Return the number of registered factories.</p>
+     *
+     * @return the number of factories registered at the time of the call.
+     */
+    int32_t countFactories(void) const;
+
+private:
+
+    friend class ::ICUServiceTest; // give tests access to countFactories.
+};
+
+U_NAMESPACE_END
+
+    /* UCONFIG_NO_SERVICE */
+#endif
+
+    /* ICUSERV_H */
+#endif
+
diff --git a/icu/source/common/servlk.cpp b/icu/source/common/servlk.cpp
new file mode 100644
index 0000000..b620414
--- /dev/null
+++ b/icu/source/common/servlk.cpp
@@ -0,0 +1,187 @@
+/**
+ *******************************************************************************
+ * Copyright (C) 2001-2004, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ *
+ *******************************************************************************
+ */
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_SERVICE
+
+#include "unicode/resbund.h"
+#include "uresimp.h"
+#include "cmemory.h"
+#include "servloc.h"
+#include "ustrfmt.h"
+#include "uhash.h"
+#include "charstr.h"
+#include "ucln_cmn.h"
+#include "uassert.h"
+
+#define UNDERSCORE_CHAR ((UChar)0x005f)
+#define AT_SIGN_CHAR    ((UChar)64)
+#define PERIOD_CHAR     ((UChar)46)
+
+U_NAMESPACE_BEGIN
+
+LocaleKey*
+LocaleKey::createWithCanonicalFallback(const UnicodeString* primaryID,
+                                       const UnicodeString* canonicalFallbackID,
+                                       UErrorCode& status)
+{
+    return LocaleKey::createWithCanonicalFallback(primaryID, canonicalFallbackID, KIND_ANY, status);
+}
+
+LocaleKey*
+LocaleKey::createWithCanonicalFallback(const UnicodeString* primaryID,
+                                       const UnicodeString* canonicalFallbackID,
+                                       int32_t kind,
+                                       UErrorCode& status)
+{
+    if (primaryID == NULL || U_FAILURE(status)) {
+        return NULL;
+    }
+    UnicodeString canonicalPrimaryID;
+    LocaleUtility::canonicalLocaleString(primaryID, canonicalPrimaryID);
+    return new LocaleKey(*primaryID, canonicalPrimaryID, canonicalFallbackID, kind);
+}
+
+LocaleKey::LocaleKey(const UnicodeString& primaryID,
+                     const UnicodeString& canonicalPrimaryID,
+                     const UnicodeString* canonicalFallbackID,
+                     int32_t kind)
+  : ICUServiceKey(primaryID)
+  , _kind(kind)
+  , _primaryID(canonicalPrimaryID)
+  , _fallbackID()
+  , _currentID()
+{
+    _fallbackID.setToBogus();
+    if (_primaryID.length() != 0) {
+        if (canonicalFallbackID != NULL && _primaryID != *canonicalFallbackID) {
+            _fallbackID = *canonicalFallbackID;
+        }
+    }
+
+    _currentID = _primaryID;
+}
+
+LocaleKey::~LocaleKey() {}
+
+UnicodeString&
+LocaleKey::prefix(UnicodeString& result) const {
+    if (_kind != KIND_ANY) {
+        UChar buffer[64];
+        uprv_itou(buffer, 64, _kind, 10, 0);
+        UnicodeString temp(buffer);
+        result.append(temp);
+    }
+    return result;
+}
+
+int32_t
+LocaleKey::kind() const {
+    return _kind;
+}
+
+UnicodeString&
+LocaleKey::canonicalID(UnicodeString& result) const {
+    return result.append(_primaryID);
+}
+
+UnicodeString&
+LocaleKey::currentID(UnicodeString& result) const {
+    if (!_currentID.isBogus()) {
+        result.append(_currentID);
+    }
+    return result;
+}
+
+UnicodeString&
+LocaleKey::currentDescriptor(UnicodeString& result) const {
+    if (!_currentID.isBogus()) {
+        prefix(result).append(PREFIX_DELIMITER).append(_currentID);
+    } else {
+        result.setToBogus();
+    }
+    return result;
+}
+
+Locale&
+LocaleKey::canonicalLocale(Locale& result) const {
+    return LocaleUtility::initLocaleFromName(_primaryID, result);
+}
+
+Locale&
+LocaleKey::currentLocale(Locale& result) const {
+    return LocaleUtility::initLocaleFromName(_currentID, result);
+}
+
+UBool
+LocaleKey::fallback() {
+    if (!_currentID.isBogus()) {
+        int x = _currentID.lastIndexOf(UNDERSCORE_CHAR);
+        if (x != -1) {
+            _currentID.remove(x); // truncate current or fallback, whichever we're pointing to
+            return TRUE;
+        }
+
+        if (!_fallbackID.isBogus()) {
+            _currentID = _fallbackID;
+            _fallbackID.setToBogus();
+            return TRUE;
+        }
+
+        if (_currentID.length() > 0) {
+            _currentID.remove(0); // completely truncate
+            return TRUE;
+        }
+
+        _currentID.setToBogus();
+    }
+
+    return FALSE;
+}
+
+UBool
+LocaleKey::isFallbackOf(const UnicodeString& id) const {
+    UnicodeString temp(id);
+    parseSuffix(temp);
+    return temp.indexOf(_primaryID) == 0 &&
+        (temp.length() == _primaryID.length() ||
+        temp.charAt(_primaryID.length()) == UNDERSCORE_CHAR);
+}
+
+#ifdef SERVICE_DEBUG
+UnicodeString&
+LocaleKey::debug(UnicodeString& result) const
+{
+    ICUServiceKey::debug(result);
+    result.append(" kind: ");
+    result.append(_kind);
+    result.append(" primaryID: ");
+    result.append(_primaryID);
+    result.append(" fallbackID: ");
+    result.append(_fallbackID);
+    result.append(" currentID: ");
+    result.append(_currentID);
+    return result;
+}
+
+UnicodeString&
+LocaleKey::debugClass(UnicodeString& result) const
+{
+    return result.append("LocaleKey ");
+}
+#endif
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LocaleKey)
+
+U_NAMESPACE_END
+
+/* !UCONFIG_NO_SERVICE */
+#endif
+
+
diff --git a/icu/source/common/servlkf.cpp b/icu/source/common/servlkf.cpp
new file mode 100644
index 0000000..c455080
--- /dev/null
+++ b/icu/source/common/servlkf.cpp
@@ -0,0 +1,151 @@
+/**
+ *******************************************************************************
+ * Copyright (C) 2001-2005, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ *
+ *******************************************************************************
+ */
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_SERVICE
+
+#include "unicode/resbund.h"
+#include "uresimp.h"
+#include "cmemory.h"
+#include "servloc.h"
+#include "ustrfmt.h"
+#include "uhash.h"
+#include "charstr.h"
+#include "ucln_cmn.h"
+#include "uassert.h"
+
+#define UNDERSCORE_CHAR ((UChar)0x005f)
+#define AT_SIGN_CHAR    ((UChar)64)
+#define PERIOD_CHAR     ((UChar)46)
+
+
+U_NAMESPACE_BEGIN
+
+LocaleKeyFactory::LocaleKeyFactory(int32_t coverage)
+  : _name()
+  , _coverage(coverage)
+{
+}
+
+LocaleKeyFactory::LocaleKeyFactory(int32_t coverage, const UnicodeString& name)
+  : _name(name)
+  , _coverage(coverage)
+{
+}
+
+LocaleKeyFactory::~LocaleKeyFactory() {
+}
+
+UObject*
+LocaleKeyFactory::create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const {
+    if (handlesKey(key, status)) {
+        const LocaleKey& lkey = (const LocaleKey&)key;
+        int32_t kind = lkey.kind();
+        Locale loc;
+        lkey.currentLocale(loc);
+
+        return handleCreate(loc, kind, service, status);
+    }
+    return NULL;
+}
+
+UBool
+LocaleKeyFactory::handlesKey(const ICUServiceKey& key, UErrorCode& status) const {
+    const Hashtable* supported = getSupportedIDs(status);
+    if (supported) {
+        UnicodeString id;
+        key.currentID(id);
+        return supported->get(id) != NULL;
+    }
+    return FALSE;
+}
+
+void
+LocaleKeyFactory::updateVisibleIDs(Hashtable& result, UErrorCode& status) const {
+    const Hashtable* supported = getSupportedIDs(status);
+    if (supported) {
+        UBool visible = (_coverage & 0x1) == 0;
+
+        const UHashElement* elem = NULL;
+        int32_t pos = 0;
+        while ((elem = supported->nextElement(pos)) != NULL) {
+            const UnicodeString& id = *((const UnicodeString*)elem->key.pointer);
+            if (!visible) {
+                result.remove(id);
+            } else {
+                result.put(id, (void*)this, status); // this is dummy non-void marker used for set semantics
+                if (U_FAILURE(status)) {
+                    break;
+                }
+            }
+        }
+    }
+}
+
+UnicodeString&
+LocaleKeyFactory::getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const {
+    if ((_coverage & 0x1) == 0) {
+        //UErrorCode status = U_ZERO_ERROR;
+        // assume if this is called on us, we support some fallback of this id
+        // if (isSupportedID(id, status)) {
+            Locale loc;
+            LocaleUtility::initLocaleFromName(id, loc);
+            return loc.getDisplayName(locale, result);
+        // }
+    }
+    result.setToBogus();
+    return result;
+}
+
+UObject*
+LocaleKeyFactory::handleCreate(const Locale& /* loc */, 
+                   int32_t /* kind */, 
+                   const ICUService* /* service */, 
+                   UErrorCode& /* status */) const {
+    return NULL;
+}
+
+//UBool
+//LocaleKeyFactory::isSupportedID(const UnicodeString& id, UErrorCode& status) const {
+//    const Hashtable* ids = getSupportedIDs(status);
+//    return ids && ids->get(id);
+//}
+
+const Hashtable*
+LocaleKeyFactory::getSupportedIDs(UErrorCode& /* status */) const {
+    return NULL;
+}
+
+#ifdef SERVICE_DEBUG
+UnicodeString&
+LocaleKeyFactory::debug(UnicodeString& result) const
+{
+    debugClass(result);
+    result.append(", name: ");
+    result.append(_name);
+    result.append(", coverage: ");
+    result.append(_coverage);
+    return result;
+}
+
+UnicodeString&
+LocaleKeyFactory::debugClass(UnicodeString& result) const
+{
+  return result.append("LocaleKeyFactory");
+}
+#endif
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LocaleKeyFactory)
+
+U_NAMESPACE_END
+
+/* !UCONFIG_NO_SERVICE */
+#endif
+
+
diff --git a/icu/source/common/servloc.h b/icu/source/common/servloc.h
new file mode 100644
index 0000000..d08b09e
--- /dev/null
+++ b/icu/source/common/servloc.h
@@ -0,0 +1,550 @@
+/**
+ *******************************************************************************
+ * Copyright (C) 2001-2005, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ *
+ *******************************************************************************
+ */
+#ifndef ICULSERV_H
+#define ICULSERV_H
+
+#include "unicode/utypes.h"
+
+#if UCONFIG_NO_SERVICE
+
+U_NAMESPACE_BEGIN
+
+/*
+ * Allow the declaration of APIs with pointers to ICUService
+ * even when service is removed from the build.
+ */
+class ICULocaleService;
+
+U_NAMESPACE_END
+
+#else
+
+#include "unicode/unistr.h"
+#include "unicode/locid.h"
+#include "unicode/strenum.h"
+
+#include "hash.h"
+#include "uvector.h"
+
+#include "serv.h"
+#include "locutil.h"
+
+U_NAMESPACE_BEGIN
+
+class ICULocaleService;
+
+class LocaleKey;
+class LocaleKeyFactory;
+class SimpleLocaleKeyFactory;
+class ServiceListener;
+
+/*
+ ******************************************************************
+ */
+
+/**
+ * A subclass of Key that implements a locale fallback mechanism.
+ * The first locale to search for is the locale provided by the
+ * client, and the fallback locale to search for is the current
+ * default locale.  If a prefix is present, the currentDescriptor
+ * includes it before the locale proper, separated by "/".  This
+ * is the default key instantiated by ICULocaleService.</p>
+ *
+ * <p>Canonicalization adjusts the locale string so that the
+ * section before the first understore is in lower case, and the rest
+ * is in upper case, with no trailing underscores.</p> 
+ */
+
+class U_COMMON_API LocaleKey : public ICUServiceKey {
+  private: 
+    int32_t _kind;
+    UnicodeString _primaryID;
+    UnicodeString _fallbackID;
+    UnicodeString _currentID;
+
+  public:
+    enum {
+        KIND_ANY = -1
+    };
+
+    /**
+     * Create a LocaleKey with canonical primary and fallback IDs.
+     */
+    static LocaleKey* createWithCanonicalFallback(const UnicodeString* primaryID, 
+                                                  const UnicodeString* canonicalFallbackID,
+                                                  UErrorCode& status);
+
+    /**
+     * Create a LocaleKey with canonical primary and fallback IDs.
+     */
+    static LocaleKey* createWithCanonicalFallback(const UnicodeString* primaryID, 
+                                                  const UnicodeString* canonicalFallbackID, 
+                                                  int32_t kind,
+                                                  UErrorCode& status);
+
+  protected:
+    /**
+     * PrimaryID is the user's requested locale string,
+     * canonicalPrimaryID is this string in canonical form,
+     * fallbackID is the current default locale's string in
+     * canonical form.
+     */
+    LocaleKey(const UnicodeString& primaryID, 
+              const UnicodeString& canonicalPrimaryID, 
+              const UnicodeString* canonicalFallbackID, 
+              int32_t kind);
+
+ public:
+    /**
+     * Append the prefix associated with the kind, or nothing if the kind is KIND_ANY.
+     */
+    virtual UnicodeString& prefix(UnicodeString& result) const;
+
+    /**
+     * Return the kind code associated with this key.
+     */
+    virtual int32_t kind() const;
+
+    /**
+     * Return the canonicalID.
+     */
+    virtual UnicodeString& canonicalID(UnicodeString& result) const;
+
+    /**
+     * Return the currentID.
+     */
+    virtual UnicodeString& currentID(UnicodeString& result) const;
+
+    /**
+     * Return the (canonical) current descriptor, or null if no current id.
+     */
+    virtual UnicodeString& currentDescriptor(UnicodeString& result) const;
+
+    /**
+     * Convenience method to return the locale corresponding to the (canonical) original ID.
+     */
+    virtual Locale& canonicalLocale(Locale& result) const;
+
+    /**
+     * Convenience method to return the locale corresponding to the (canonical) current ID.
+     */
+    virtual Locale& currentLocale(Locale& result) const;
+
+    /**
+     * If the key has a fallback, modify the key and return true,
+     * otherwise return false.</p>
+     *
+     * <p>First falls back through the primary ID, then through
+     * the fallbackID.  The final fallback is the empty string,
+     * unless the primary id was the empty string, in which case
+     * there is no fallback.  
+     */
+    virtual UBool fallback();
+
+    /**
+     * Return true if a key created from id matches, or would eventually
+     * fallback to match, the canonical ID of this key.  
+     */
+    virtual UBool isFallbackOf(const UnicodeString& id) const;
+    
+ public:
+    /**
+     * UObject boilerplate.
+     */
+    static UClassID U_EXPORT2 getStaticClassID();
+
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * Destructor.
+     */
+    virtual ~LocaleKey();
+
+#ifdef SERVICE_DEBUG
+ public:
+    virtual UnicodeString& debug(UnicodeString& result) const;
+    virtual UnicodeString& debugClass(UnicodeString& result) const;
+#endif
+
+};
+
+/*
+ ******************************************************************
+ */
+
+/**
+ * A subclass of ICUServiceFactory that uses LocaleKeys, and is able to
+ * 'cover' more specific locales with more general locales that it
+ * supports.  
+ *
+ * <p>Coverage may be either of the values VISIBLE or INVISIBLE.
+ *
+ * <p>'Visible' indicates that the specific locale(s) supported by
+ * the factory are registered in getSupportedIDs, 'Invisible'
+ * indicates that they are not.
+ *
+ * <p>Localization of visible ids is handled
+ * by the handling factory, regardless of kind.
+ */
+class U_COMMON_API LocaleKeyFactory : public ICUServiceFactory {
+protected:
+    const UnicodeString _name;
+    const int32_t _coverage;
+
+public:
+    enum {
+        /**
+         * Coverage value indicating that the factory makes
+         * its locales visible, and does not cover more specific 
+         * locales.
+         */
+        VISIBLE = 0,
+
+        /**
+         * Coverage value indicating that the factory does not make
+         * its locales visible, and does not cover more specific
+         * locales.
+         */
+        INVISIBLE = 1
+    };
+
+    /**
+     * Destructor.
+     */
+    virtual ~LocaleKeyFactory();
+
+protected:
+    /**
+     * Constructor used by subclasses.
+     */
+    LocaleKeyFactory(int32_t coverage);
+
+    /**
+     * Constructor used by subclasses.
+     */
+    LocaleKeyFactory(int32_t coverage, const UnicodeString& name);
+
+    /**
+     * Implement superclass abstract method.  This checks the currentID of
+     * the key against the supported IDs, and passes the canonicalLocale and
+     * kind off to handleCreate (which subclasses must implement).
+     */
+public:
+    virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const;
+
+protected:
+    virtual UBool handlesKey(const ICUServiceKey& key, UErrorCode& status) const;
+
+public:
+    /**
+     * Override of superclass method.  This adjusts the result based
+     * on the coverage rule for this factory.
+     */
+    virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const;
+
+    /**
+     * Return a localized name for the locale represented by id.
+     */
+    virtual UnicodeString& getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const;
+
+protected:
+    /**
+     * Utility method used by create(ICUServiceKey, ICUService).  Subclasses can implement
+     * this instead of create.  The default returns NULL.
+     */
+    virtual UObject* handleCreate(const Locale& loc, int32_t kind, const ICUService* service, UErrorCode& status) const;
+
+   /**
+     * Return true if this id is one the factory supports (visible or 
+     * otherwise).
+     */
+ //   virtual UBool isSupportedID(const UnicodeString& id, UErrorCode& status) const;
+
+   /**
+     * Return the set of ids that this factory supports (visible or 
+     * otherwise).  This can be called often and might need to be
+     * cached if it is expensive to create.
+     */
+    virtual const Hashtable* getSupportedIDs(UErrorCode& status) const;
+
+public:
+    /**
+     * UObject boilerplate.
+     */
+    static UClassID U_EXPORT2 getStaticClassID();
+
+    virtual UClassID getDynamicClassID() const;
+
+#ifdef SERVICE_DEBUG
+ public:
+    virtual UnicodeString& debug(UnicodeString& result) const;
+    virtual UnicodeString& debugClass(UnicodeString& result) const;
+#endif
+
+};
+
+/*
+ ******************************************************************
+ */
+
+/**
+ * A LocaleKeyFactory that just returns a single object for a kind/locale.
+ */
+
+class U_COMMON_API SimpleLocaleKeyFactory : public LocaleKeyFactory {
+ private:
+    UObject* _obj;
+    UnicodeString _id;
+    const int32_t _kind;
+
+ public:
+    SimpleLocaleKeyFactory(UObject* objToAdopt, 
+                           const UnicodeString& locale, 
+                           int32_t kind, 
+                           int32_t coverage);
+
+    SimpleLocaleKeyFactory(UObject* objToAdopt, 
+                           const Locale& locale, 
+                           int32_t kind, 
+                           int32_t coverage);
+
+    /**
+     * Destructor.
+     */
+    virtual ~SimpleLocaleKeyFactory();
+
+    /**
+     * Override of superclass method.  Returns the service object if kind/locale match.  Service is not used.
+     */
+    virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const;
+
+    /**
+     * Override of superclass method.  This adjusts the result based
+     * on the coverage rule for this factory.
+     */
+    virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const;
+
+ protected:
+    /**
+     * Return true if this id is equal to the locale name.
+     */
+    //virtual UBool isSupportedID(const UnicodeString& id, UErrorCode& status) const;
+
+
+public:
+    /**
+     * UObject boilerplate.
+     */
+    static UClassID U_EXPORT2 getStaticClassID();
+
+    virtual UClassID getDynamicClassID() const;
+
+#ifdef SERVICE_DEBUG
+ public:
+    virtual UnicodeString& debug(UnicodeString& result) const;
+    virtual UnicodeString& debugClass(UnicodeString& result) const;
+#endif
+
+};
+
+/*
+ ******************************************************************
+ */
+
+/**
+ * A LocaleKeyFactory that creates a service based on the ICU locale data.
+ * This is a base class for most ICU factories.  Subclasses instantiate it
+ * with a constructor that takes a bundle name, which determines the supported
+ * IDs.  Subclasses then override handleCreate to create the actual service
+ * object.  The default implementation returns a resource bundle.
+ */
+class U_COMMON_API ICUResourceBundleFactory : public LocaleKeyFactory 
+{
+ protected:
+    UnicodeString _bundleName;
+
+ public:
+    /**
+     * Convenience constructor that uses the main ICU bundle name.
+     */
+    ICUResourceBundleFactory();
+
+    /**
+     * A service factory based on ICU resource data in resources with
+     * the given name.  This should be a 'path' that can be passed to
+     * ures_openAvailableLocales, such as U_ICUDATA or U_ICUDATA_COLL.
+     * The empty string is equivalent to U_ICUDATA.
+     */
+    ICUResourceBundleFactory(const UnicodeString& bundleName);
+
+    /**
+     * Destructor
+     */
+    virtual ~ICUResourceBundleFactory();
+
+protected:
+    /**
+     * Return the supported IDs.  This is the set of all locale names in ICULocaleData.
+     */
+    virtual const Hashtable* getSupportedIDs(UErrorCode& status) const;
+
+    /**
+     * Create the service.  The default implementation returns the resource bundle
+     * for the locale, ignoring kind, and service.
+     */
+    virtual UObject* handleCreate(const Locale& loc, int32_t kind, const ICUService* service, UErrorCode& status) const;
+
+public:
+    /**
+     * UObject boilerplate.
+     */
+    static UClassID U_EXPORT2 getStaticClassID();
+    virtual UClassID getDynamicClassID() const;
+
+
+#ifdef SERVICE_DEBUG
+ public:
+    virtual UnicodeString& debug(UnicodeString& result) const;
+    virtual UnicodeString& debugClass(UnicodeString& result) const;
+#endif
+
+};
+
+/*
+ ******************************************************************
+ */
+
+class U_COMMON_API ICULocaleService : public ICUService 
+{
+ private:
+  Locale fallbackLocale;
+  UnicodeString fallbackLocaleName;
+  UMTX llock;
+
+ public:
+  /**
+   * Construct an ICULocaleService.
+   */
+  ICULocaleService();
+
+  /**
+   * Construct an ICULocaleService with a name (useful for debugging).
+   */
+  ICULocaleService(const UnicodeString& name);
+
+  /**
+   * Destructor.
+   */
+  virtual ~ICULocaleService();
+
+#if 0
+  // redeclare because of overload resolution rules?
+  // no, causes ambiguities since both UnicodeString and Locale have constructors that take a const char*
+  // need some compiler flag to remove warnings 
+  UObject* get(const UnicodeString& descriptor, UErrorCode& status) const {
+    return ICUService::get(descriptor, status);
+  }
+
+  UObject* get(const UnicodeString& descriptor, UnicodeString* actualReturn, UErrorCode& status) const {
+    return ICUService::get(descriptor, actualReturn, status);
+  }
+#endif
+
+  /**
+   * Convenience override for callers using locales.  This calls
+   * get(Locale, int, Locale[]) with KIND_ANY for kind and null for
+   * actualReturn.
+   */
+  UObject* get(const Locale& locale, UErrorCode& status) const;
+
+  /**
+   * Convenience override for callers using locales.  This calls
+   * get(Locale, int, Locale[]) with a null actualReturn.
+   */
+  UObject* get(const Locale& locale, int32_t kind, UErrorCode& status) const;
+
+  /**
+   * Convenience override for callers using locales. This calls
+   * get(Locale, String, Locale[]) with a null kind.
+   */
+  UObject* get(const Locale& locale, Locale* actualReturn, UErrorCode& status) const;
+                   
+  /**
+   * Convenience override for callers using locales.  This uses
+   * createKey(Locale.toString(), kind) to create a key, calls getKey, and then
+   * if actualReturn is not null, returns the actualResult from
+   * getKey (stripping any prefix) into a Locale.  
+   */
+  UObject* get(const Locale& locale, int32_t kind, Locale* actualReturn, UErrorCode& status) const;
+
+  /**
+   * Convenience override for callers using locales.  This calls
+   * registerObject(Object, Locale, int32_t kind, int coverage)
+   * passing KIND_ANY for the kind, and VISIBLE for the coverage.
+   */
+  virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, UErrorCode& status);
+
+  /**
+   * Convenience function for callers using locales.  This calls
+   * registerObject(Object, Locale, int kind, int coverage)
+   * passing VISIBLE for the coverage.
+   */
+  virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, UErrorCode& status);
+
+  /**
+   * Convenience function for callers using locales.  This  instantiates
+   * a SimpleLocaleKeyFactory, and registers the factory.
+   */
+  virtual URegistryKey registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, int32_t coverage, UErrorCode& status);
+
+
+  /**
+   * (Stop compiler from complaining about hidden overrides.)
+   * Since both UnicodeString and Locale have constructors that take const char*, adding a public
+   * method that takes UnicodeString causes ambiguity at call sites that use const char*.
+   * We really need a flag that is understood by all compilers that will suppress the warning about
+   * hidden overrides.
+   */
+  virtual URegistryKey registerInstance(UObject* objToAdopt, const UnicodeString& locale, UBool visible, UErrorCode& status);
+
+  /**
+   * Convenience method for callers using locales.  This returns the standard
+   * service ID enumeration.
+   */
+  virtual StringEnumeration* getAvailableLocales(void) const;
+
+ protected:
+
+  /**
+   * Return the name of the current fallback locale.  If it has changed since this was
+   * last accessed, the service cache is cleared.
+   */
+  const UnicodeString& validateFallbackLocale() const;
+
+  /**
+   * Override superclass createKey method.
+   */
+  virtual ICUServiceKey* createKey(const UnicodeString* id, UErrorCode& status) const;
+
+  /**
+   * Additional createKey that takes a kind.
+   */
+  virtual ICUServiceKey* createKey(const UnicodeString* id, int32_t kind, UErrorCode& status) const;
+
+  friend class ServiceEnumeration;
+};
+
+U_NAMESPACE_END
+
+    /* UCONFIG_NO_SERVICE */
+#endif
+
+    /* ICULSERV_H */
+#endif
+
diff --git a/icu/source/common/servls.cpp b/icu/source/common/servls.cpp
new file mode 100644
index 0000000..b39e72e
--- /dev/null
+++ b/icu/source/common/servls.cpp
@@ -0,0 +1,297 @@
+/**
+ *******************************************************************************
+ * Copyright (C) 2001-2004, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ *
+ *******************************************************************************
+ */
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_SERVICE
+
+#include "unicode/resbund.h"
+#include "uresimp.h"
+#include "cmemory.h"
+#include "servloc.h"
+#include "ustrfmt.h"
+#include "uhash.h"
+#include "charstr.h"
+#include "ucln_cmn.h"
+#include "uassert.h"
+
+#define UNDERSCORE_CHAR ((UChar)0x005f)
+#define AT_SIGN_CHAR    ((UChar)64)
+#define PERIOD_CHAR     ((UChar)46)
+
+U_NAMESPACE_BEGIN
+
+ICULocaleService::ICULocaleService()
+  : fallbackLocale(Locale::getDefault())
+  , llock(0)
+{
+  umtx_init(&llock);
+}
+
+ICULocaleService::ICULocaleService(const UnicodeString& dname)
+  : ICUService(dname)
+  , fallbackLocale(Locale::getDefault())
+  , llock(0)
+{
+  umtx_init(&llock);
+}
+
+ICULocaleService::~ICULocaleService()
+{
+  umtx_destroy(&llock);
+}
+
+UObject*
+ICULocaleService::get(const Locale& locale, UErrorCode& status) const
+{
+    return get(locale, LocaleKey::KIND_ANY, NULL, status);
+}
+
+UObject*
+ICULocaleService::get(const Locale& locale, int32_t kind, UErrorCode& status) const
+{
+    return get(locale, kind, NULL, status);
+}
+
+UObject*
+ICULocaleService::get(const Locale& locale, Locale* actualReturn, UErrorCode& status) const
+{
+    return get(locale, LocaleKey::KIND_ANY, actualReturn, status);
+}
+
+UObject*
+ICULocaleService::get(const Locale& locale, int32_t kind, Locale* actualReturn, UErrorCode& status) const
+{
+    UObject* result = NULL;
+    if (U_FAILURE(status)) {
+        return result;
+    }
+
+    UnicodeString locName(locale.getName(), -1, US_INV);
+    if (locName.isBogus()) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+    } else {
+        ICUServiceKey* key = createKey(&locName, kind, status);
+        if (key) {
+            if (actualReturn == NULL) {
+                result = getKey(*key, status);
+            } else {
+                UnicodeString temp;
+                result = getKey(*key, &temp, status);
+
+                if (result != NULL) {
+                    key->parseSuffix(temp);
+                    LocaleUtility::initLocaleFromName(temp, *actualReturn);
+                }
+            }
+            delete key;
+        }
+    }
+    return result;
+}
+
+
+URegistryKey
+ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, 
+    UBool visible, UErrorCode& status)
+{
+    Locale loc;
+    LocaleUtility::initLocaleFromName(locale, loc);
+    return registerInstance(objToAdopt, loc, LocaleKey::KIND_ANY, 
+        visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE, status);
+}
+
+URegistryKey
+ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, UErrorCode& status)
+{
+    return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status);
+}
+
+URegistryKey
+ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, UErrorCode& status)
+{
+    return registerInstance(objToAdopt, locale, kind, LocaleKeyFactory::VISIBLE, status);
+}
+
+URegistryKey
+ICULocaleService::registerInstance(UObject* objToAdopt, const Locale& locale, int32_t kind, int32_t coverage, UErrorCode& status)
+{
+    ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage);
+    if (factory != NULL) {
+        return registerFactory(factory, status);
+    }
+    delete objToAdopt;
+    return NULL;
+}
+
+#if 0
+URegistryKey
+ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UErrorCode& status)
+{
+    return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY, LocaleKeyFactory::VISIBLE, status);
+}
+
+URegistryKey
+ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, UBool visible, UErrorCode& status)
+{
+    return registerInstance(objToAdopt, locale, LocaleKey::KIND_ANY,
+                            visible ? LocaleKeyFactory::VISIBLE : LocaleKeyFactory::INVISIBLE,
+                            status);
+}
+
+URegistryKey
+ICULocaleService::registerInstance(UObject* objToAdopt, const UnicodeString& locale, int32_t kind, int32_t coverage, UErrorCode& status)
+{
+    ICUServiceFactory * factory = new SimpleLocaleKeyFactory(objToAdopt, locale, kind, coverage);
+    if (factory != NULL) {
+        return registerFactory(factory, status);
+    }
+    delete objToAdopt;
+    return NULL;
+}
+#endif
+
+class ServiceEnumeration : public StringEnumeration {
+private:
+    const ICULocaleService* _service;
+    int32_t _timestamp;
+    UVector _ids;
+    int32_t _pos;
+
+private:
+    ServiceEnumeration(const ICULocaleService* service, UErrorCode &status)
+        : _service(service)
+        , _timestamp(service->getTimestamp())
+        , _ids(uhash_deleteUnicodeString, NULL, status)
+        , _pos(0)
+    {
+        _service->getVisibleIDs(_ids, status);
+    }
+
+    ServiceEnumeration(const ServiceEnumeration &other, UErrorCode &status)
+        : _service(other._service)
+        , _timestamp(other._timestamp)
+        , _ids(uhash_deleteUnicodeString, NULL, status)
+        , _pos(0)
+    {
+        if(U_SUCCESS(status)) {
+            int32_t i, length;
+
+            length = other._ids.size();
+            for(i = 0; i < length; ++i) {
+                _ids.addElement(((UnicodeString *)other._ids.elementAt(i))->clone(), status);
+            }
+
+            if(U_SUCCESS(status)) {
+                _pos = other._pos;
+            }
+        }
+    }
+
+public:
+    static ServiceEnumeration* create(const ICULocaleService* service) {
+        UErrorCode status = U_ZERO_ERROR;
+        ServiceEnumeration* result = new ServiceEnumeration(service, status);
+        if (U_SUCCESS(status)) {
+            return result;
+        }
+        delete result;
+        return NULL;
+    }
+
+    virtual ~ServiceEnumeration() {}
+
+    virtual StringEnumeration *clone() const {
+        UErrorCode status = U_ZERO_ERROR;
+        ServiceEnumeration *cl = new ServiceEnumeration(*this, status);
+        if(U_FAILURE(status)) {
+            delete cl;
+            cl = NULL;
+        }
+        return cl;
+    }
+
+    UBool upToDate(UErrorCode& status) const {
+        if (U_SUCCESS(status)) {
+            if (_timestamp == _service->getTimestamp()) {
+                return TRUE;
+            }
+            status = U_ENUM_OUT_OF_SYNC_ERROR;
+        }
+        return FALSE;
+    }
+
+    virtual int32_t count(UErrorCode& status) const {
+        return upToDate(status) ? _ids.size() : 0;
+    }
+
+    virtual const UnicodeString* snext(UErrorCode& status) {
+        if (upToDate(status) && (_pos < _ids.size())) {
+            return (const UnicodeString*)_ids[_pos++];
+        }
+        return NULL;
+    }
+
+    virtual void reset(UErrorCode& status) {
+        if (status == U_ENUM_OUT_OF_SYNC_ERROR) {
+            status = U_ZERO_ERROR;
+        }
+        if (U_SUCCESS(status)) {
+            _timestamp = _service->getTimestamp();
+            _pos = 0;
+            _service->getVisibleIDs(_ids, status);
+        }
+    }
+
+public:
+    static UClassID U_EXPORT2 getStaticClassID(void);
+    virtual UClassID getDynamicClassID(void) const;
+};
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ServiceEnumeration)
+
+StringEnumeration*
+ICULocaleService::getAvailableLocales(void) const
+{
+    return ServiceEnumeration::create(this);
+}
+
+const UnicodeString&
+ICULocaleService::validateFallbackLocale() const
+{
+    const Locale&     loc    = Locale::getDefault();
+    ICULocaleService* ncThis = (ICULocaleService*)this;
+    {
+        Mutex mutex(&ncThis->llock);
+        if (loc != fallbackLocale) {
+            ncThis->fallbackLocale = loc;
+            LocaleUtility::initNameFromLocale(loc, ncThis->fallbackLocaleName);
+            ncThis->clearServiceCache();
+        }
+    }
+    return fallbackLocaleName;
+}
+
+ICUServiceKey*
+ICULocaleService::createKey(const UnicodeString* id, UErrorCode& status) const
+{
+    return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), status);
+}
+
+ICUServiceKey*
+ICULocaleService::createKey(const UnicodeString* id, int32_t kind, UErrorCode& status) const
+{
+    return LocaleKey::createWithCanonicalFallback(id, &validateFallbackLocale(), kind, status);
+}
+
+U_NAMESPACE_END
+
+/* !UCONFIG_NO_SERVICE */
+#endif
+
+
diff --git a/icu/source/common/servnotf.cpp b/icu/source/common/servnotf.cpp
new file mode 100644
index 0000000..6adf52e
--- /dev/null
+++ b/icu/source/common/servnotf.cpp
@@ -0,0 +1,118 @@
+/**
+ *******************************************************************************
+ * Copyright (C) 2001-2006, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ */
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_SERVICE
+
+#include "servnotf.h"
+#ifdef NOTIFIER_DEBUG
+#include <stdio.h>
+#endif
+
+U_NAMESPACE_BEGIN
+
+EventListener::~EventListener() {}
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(EventListener)
+
+ICUNotifier::ICUNotifier(void) 
+: notifyLock(0), listeners(NULL) 
+{
+    umtx_init(&notifyLock);
+}
+
+ICUNotifier::~ICUNotifier(void) {
+    {
+        Mutex lmx(&notifyLock);
+        delete listeners;
+        listeners = NULL;
+    }
+    umtx_destroy(&notifyLock);
+}
+
+
+void 
+ICUNotifier::addListener(const EventListener* l, UErrorCode& status) 
+{
+    if (U_SUCCESS(status)) {
+        if (l == NULL) {
+            status = U_ILLEGAL_ARGUMENT_ERROR;
+            return;
+        }
+
+        if (acceptsListener(*l)) {
+            Mutex lmx(&notifyLock);
+            if (listeners == NULL) {
+                listeners = new UVector(5, status);
+            } else {
+                for (int i = 0, e = listeners->size(); i < e; ++i) {
+                    const EventListener* el = (const EventListener*)(listeners->elementAt(i));
+                    if (l == el) {
+                        return;
+                    }
+                }
+            }
+
+            listeners->addElement((void*)l, status); // cast away const
+        }
+#ifdef NOTIFIER_DEBUG
+        else {
+            fprintf(stderr, "Listener invalid for this notifier.");
+            exit(1);
+        }
+#endif
+    }
+}
+
+void 
+ICUNotifier::removeListener(const EventListener *l, UErrorCode& status) 
+{
+    if (U_SUCCESS(status)) {
+        if (l == NULL) {
+            status = U_ILLEGAL_ARGUMENT_ERROR;
+            return;
+        }
+
+        {
+            Mutex lmx(&notifyLock);
+            if (listeners != NULL) {
+                // identity equality check
+                for (int i = 0, e = listeners->size(); i < e; ++i) {
+                    const EventListener* el = (const EventListener*)listeners->elementAt(i);
+                    if (l == el) {
+                        listeners->removeElementAt(i);
+                        if (listeners->size() == 0) {
+                            delete listeners;
+                            listeners = NULL;
+                        }
+                        return;
+                    }
+                }
+            }
+        }
+    }
+}
+
+void 
+ICUNotifier::notifyChanged(void) 
+{
+    if (listeners != NULL) {
+        Mutex lmx(&notifyLock);
+        if (listeners != NULL) {
+            for (int i = 0, e = listeners->size(); i < e; ++i) {
+                EventListener* el = (EventListener*)listeners->elementAt(i);
+                notifyListener(*el);
+            }
+        }
+    }
+}
+
+U_NAMESPACE_END
+
+/* UCONFIG_NO_SERVICE */
+#endif
+
diff --git a/icu/source/common/servnotf.h b/icu/source/common/servnotf.h
new file mode 100644
index 0000000..19c2d69
--- /dev/null
+++ b/icu/source/common/servnotf.h
@@ -0,0 +1,124 @@
+/**
+ *******************************************************************************
+ * Copyright (C) 2001-2004, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ */
+#ifndef ICUNOTIF_H
+#define ICUNOTIF_H
+
+#include "unicode/utypes.h"
+
+#if UCONFIG_NO_SERVICE
+
+U_NAMESPACE_BEGIN
+
+/*
+ * Allow the declaration of APIs with pointers to BreakIterator
+ * even when break iteration is removed from the build.
+ */
+class ICUNotifier;
+
+U_NAMESPACE_END
+
+#else
+
+#include "unicode/uobject.h"
+#include "unicode/unistr.h"
+
+#include "mutex.h"
+#include "uvector.h"
+
+U_NAMESPACE_BEGIN
+
+class U_COMMON_API EventListener : public UObject {
+public: 
+    virtual ~EventListener();
+
+public:
+    static UClassID U_EXPORT2 getStaticClassID();
+
+    virtual UClassID getDynamicClassID() const;
+
+public:
+#ifdef SERVICE_DEBUG
+    virtual UnicodeString& debug(UnicodeString& result) const {
+      return debugClass(result);
+    }
+
+    virtual UnicodeString& debugClass(UnicodeString& result) const {
+      return result.append("Key");
+    }
+#endif
+};
+
+/**
+ * <p>Abstract implementation of a notification facility.  Clients add
+ * EventListeners with addListener and remove them with removeListener.
+ * Notifiers call notifyChanged when they wish to notify listeners.
+ * This queues the listener list on the notification thread, which
+ * eventually dequeues the list and calls notifyListener on each
+ * listener in the list.</p>
+ *
+ * <p>Subclasses override acceptsListener and notifyListener 
+ * to add type-safe notification.  AcceptsListener should return
+ * true if the listener is of the appropriate type; ICUNotifier
+ * itself will ensure the listener is non-null and that the
+ * identical listener is not already registered with the Notifier.
+ * NotifyListener should cast the listener to the appropriate 
+ * type and call the appropriate method on the listener.
+ */
+
+class U_COMMON_API ICUNotifier : public UMemory  {
+private: UMTX notifyLock;
+private: UVector* listeners;
+         
+public: 
+    ICUNotifier(void);
+    
+    virtual ~ICUNotifier(void);
+    
+    /**
+     * Add a listener to be notified when notifyChanged is called.
+     * The listener must not be null. AcceptsListener must return
+     * true for the listener.  Attempts to concurrently
+     * register the identical listener more than once will be
+     * silently ignored.  
+     */
+    virtual void addListener(const EventListener* l, UErrorCode& status);
+    
+    /**
+     * Stop notifying this listener.  The listener must
+     * not be null.  Attemps to remove a listener that is
+     * not registered will be silently ignored.
+     */
+    virtual void removeListener(const EventListener* l, UErrorCode& status);
+    
+    /**
+     * ICU doesn't spawn its own threads.  All listeners are notified in
+     * the thread of the caller.  Misbehaved listeners can therefore
+     * indefinitely block the calling thread.  Callers should beware of
+     * deadlock situations.  
+     */
+    virtual void notifyChanged(void);
+    
+protected: 
+    /**
+     * Subclasses implement this to return TRUE if the listener is
+     * of the appropriate type.
+     */
+    virtual UBool acceptsListener(const EventListener& l) const = 0;
+    
+    /**
+     * Subclasses implement this to notify the listener.
+     */
+    virtual void notifyListener(EventListener& l) const = 0;
+};
+
+U_NAMESPACE_END
+
+/* UCONFIG_NO_SERVICE */
+#endif
+
+/* ICUNOTIF_H */
+#endif
diff --git a/icu/source/common/servrbf.cpp b/icu/source/common/servrbf.cpp
new file mode 100644
index 0000000..3a0227f
--- /dev/null
+++ b/icu/source/common/servrbf.cpp
@@ -0,0 +1,94 @@
+/**
+ *******************************************************************************
+ * Copyright (C) 2001-2005, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ *
+ *******************************************************************************
+ */
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_SERVICE
+
+#include "unicode/resbund.h"
+#include "uresimp.h"
+#include "cmemory.h"
+#include "servloc.h"
+#include "ustrfmt.h"
+#include "uhash.h"
+#include "charstr.h"
+#include "ucln_cmn.h"
+#include "uassert.h"
+
+#define UNDERSCORE_CHAR ((UChar)0x005f)
+#define AT_SIGN_CHAR    ((UChar)64)
+#define PERIOD_CHAR     ((UChar)46)
+
+U_NAMESPACE_BEGIN
+
+ICUResourceBundleFactory::ICUResourceBundleFactory()
+  : LocaleKeyFactory(VISIBLE)
+  , _bundleName()
+{
+}
+
+ICUResourceBundleFactory::ICUResourceBundleFactory(const UnicodeString& bundleName)
+  : LocaleKeyFactory(VISIBLE)
+  , _bundleName(bundleName)
+{
+}
+
+ICUResourceBundleFactory::~ICUResourceBundleFactory() {}
+
+const Hashtable*
+ICUResourceBundleFactory::getSupportedIDs(UErrorCode& status) const
+{
+    if (U_SUCCESS(status)) {
+        return LocaleUtility::getAvailableLocaleNames(_bundleName);
+    }
+    return NULL;
+}
+
+UObject*
+ICUResourceBundleFactory::handleCreate(const Locale& loc, int32_t /* kind */, const ICUService* /* service */, UErrorCode& status) const
+{
+    if (U_SUCCESS(status)) {
+        // _bundleName is a package name
+        // and should only contain invariant characters
+                // ??? is it always true that the max length of the bundle name is 19?
+                // who made this change? -- dlf
+        char pkg[20];
+        int32_t length;
+        length=_bundleName.extract(0, INT32_MAX, pkg, (int32_t)sizeof(pkg), US_INV);
+        if(length>=(int32_t)sizeof(pkg)) {
+            return NULL;
+        }
+        return new ResourceBundle(pkg, loc, status);
+    }
+    return NULL;
+}
+
+#ifdef SERVICE_DEBUG
+UnicodeString&
+ICUResourceBundleFactory::debug(UnicodeString& result) const
+{
+    LocaleKeyFactory::debug(result);
+    result.append(", bundle: ");
+    return result.append(_bundleName);
+}
+
+UnicodeString&
+ICUResourceBundleFactory::debugClass(UnicodeString& result) const
+{
+    return result.append("ICUResourceBundleFactory");
+}
+#endif
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ICUResourceBundleFactory)
+
+U_NAMESPACE_END
+
+/* !UCONFIG_NO_SERVICE */
+#endif
+
+
diff --git a/icu/source/common/servslkf.cpp b/icu/source/common/servslkf.cpp
new file mode 100644
index 0000000..b8afaaa
--- /dev/null
+++ b/icu/source/common/servslkf.cpp
@@ -0,0 +1,122 @@
+/**
+ *******************************************************************************
+ * Copyright (C) 2001-2005, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ *
+ *******************************************************************************
+ */
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_SERVICE
+
+#include "unicode/resbund.h"
+#include "uresimp.h"
+#include "cmemory.h"
+#include "servloc.h"
+#include "ustrfmt.h"
+#include "uhash.h"
+#include "charstr.h"
+#include "ucln_cmn.h"
+#include "uassert.h"
+
+#define UNDERSCORE_CHAR ((UChar)0x005f)
+#define AT_SIGN_CHAR    ((UChar)64)
+#define PERIOD_CHAR     ((UChar)46)
+
+U_NAMESPACE_BEGIN
+
+/*
+ ******************************************************************
+ */
+
+SimpleLocaleKeyFactory::SimpleLocaleKeyFactory(UObject* objToAdopt,
+                                               const UnicodeString& locale,
+                                               int32_t kind,
+                                               int32_t coverage)
+  : LocaleKeyFactory(coverage)
+  , _obj(objToAdopt)
+  , _id(locale)
+  , _kind(kind)
+{
+}
+
+SimpleLocaleKeyFactory::SimpleLocaleKeyFactory(UObject* objToAdopt,
+                                               const Locale& locale,
+                                               int32_t kind,
+                                               int32_t coverage)
+  : LocaleKeyFactory(coverage)
+  , _obj(objToAdopt)
+  , _id()
+  , _kind(kind)
+{
+    LocaleUtility::initNameFromLocale(locale, _id);
+}
+
+SimpleLocaleKeyFactory::~SimpleLocaleKeyFactory()
+{
+  delete _obj;
+  _obj = NULL;
+}
+
+UObject*
+SimpleLocaleKeyFactory::create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const
+{
+    if (U_SUCCESS(status)) {
+        const LocaleKey& lkey = (const LocaleKey&)key;
+        if (_kind == LocaleKey::KIND_ANY || _kind == lkey.kind()) {
+            UnicodeString keyID;
+            lkey.currentID(keyID);
+            if (_id == keyID) {
+                return service->cloneInstance(_obj);
+            }
+        }
+    }
+    return NULL;
+}
+
+//UBool
+//SimpleLocaleKeyFactory::isSupportedID(const UnicodeString& id, UErrorCode& /* status */) const
+//{
+//    return id == _id;
+//}
+
+void
+SimpleLocaleKeyFactory::updateVisibleIDs(Hashtable& result, UErrorCode& status) const
+{
+    if (U_SUCCESS(status)) {
+        if (_coverage & 0x1) {
+            result.remove(_id);
+        } else {
+            result.put(_id, (void*)this, status);
+        }
+    }
+}
+
+#ifdef SERVICE_DEBUG
+UnicodeString&
+SimpleLocaleKeyFactory::debug(UnicodeString& result) const
+{
+    LocaleKeyFactory::debug(result);
+    result.append(", id: ");
+    result.append(_id);
+    result.append(", kind: ");
+    result.append(_kind);
+    return result;
+}
+
+UnicodeString&
+SimpleLocaleKeyFactory::debugClass(UnicodeString& result) const
+{
+    return result.append("SimpleLocaleKeyFactory");
+}
+#endif
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleLocaleKeyFactory)
+
+U_NAMESPACE_END
+
+/* !UCONFIG_NO_SERVICE */
+#endif
+
+
diff --git a/icu/source/common/sprpimpl.h b/icu/source/common/sprpimpl.h
new file mode 100644
index 0000000..1422cc3
--- /dev/null
+++ b/icu/source/common/sprpimpl.h
@@ -0,0 +1,129 @@
+/*
+ *******************************************************************************
+ *
+ *   Copyright (C) 2003-2006, International Business Machines
+ *   Corporation and others.  All Rights Reserved.
+ *
+ *******************************************************************************
+ *   file name:  sprpimpl.h
+ *   encoding:   US-ASCII
+ *   tab size:   8 (not used)
+ *   indentation:4
+ *
+ *   created on: 2003feb1
+ *   created by: Ram Viswanadha
+ */
+
+#ifndef SPRPIMPL_H
+#define SPRPIMPL_H
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_IDNA
+
+#include "unicode/ustring.h"
+#include "unicode/parseerr.h"
+#include "unicode/usprep.h"
+#include "unicode/udata.h"
+#include "utrie.h"
+#include "udataswp.h"
+#include "ubidi_props.h"
+
+#define _SPREP_DATA_TYPE "spp"
+
+enum UStringPrepType{
+    USPREP_UNASSIGNED           = 0x0000 ,
+    USPREP_MAP                  = 0x0001 ,
+    USPREP_PROHIBITED           = 0x0002 , 
+    USPREP_DELETE               = 0x0003 ,
+    USPREP_TYPE_LIMIT           = 0x0004  
+};
+
+typedef enum UStringPrepType UStringPrepType;
+
+#ifdef USPREP_TYPE_NAMES_ARRAY
+static const char* usprepTypeNames[] ={
+    "UNASSIGNED" ,          
+    "MAP" , 
+    "PROHIBITED" ,        
+    "DELETE",
+    "TYPE_LIMIT" 
+};
+#endif
+
+enum{
+    _SPREP_NORMALIZATION_ON = 0x0001,
+    _SPREP_CHECK_BIDI_ON    = 0x0002
+};
+
+enum{
+    _SPREP_TYPE_THRESHOLD       = 0xFFF0,
+    _SPREP_MAX_INDEX_VALUE      = 0x3FBF,   /*16139*/ 
+    _SPREP_MAX_INDEX_TOP_LENGTH = 0x0003
+};
+
+/* indexes[] value names */
+enum {
+    _SPREP_INDEX_TRIE_SIZE                  = 0, /* number of bytes in StringPrep trie */
+    _SPREP_INDEX_MAPPING_DATA_SIZE          = 1, /* The array that contains the mapping   */
+    _SPREP_NORM_CORRECTNS_LAST_UNI_VERSION  = 2, /* The index of Unicode version of last entry in NormalizationCorrections.txt */ 
+    _SPREP_ONE_UCHAR_MAPPING_INDEX_START    = 3, /* The starting index of 1 UChar mapping index in the mapping data array */
+    _SPREP_TWO_UCHARS_MAPPING_INDEX_START   = 4, /* The starting index of 2 UChars mapping index in the mapping data array */
+    _SPREP_THREE_UCHARS_MAPPING_INDEX_START = 5, /* The starting index of 3 UChars mapping index in the mapping data array */
+    _SPREP_FOUR_UCHARS_MAPPING_INDEX_START  = 6, /* The starting index of 4 UChars mapping index in the mapping data array */
+    _SPREP_OPTIONS                          = 7, /* Bit set of options to turn on in the profile */
+    _SPREP_INDEX_TOP=16                          /* changing this requires a new formatVersion */
+};
+
+typedef struct UStringPrepKey UStringPrepKey;
+
+
+struct UStringPrepKey{
+    char* name;
+    char* path;
+};
+
+struct UStringPrepProfile{
+    int32_t indexes[_SPREP_INDEX_TOP];
+    UTrie sprepTrie;
+    const uint16_t* mappingData;
+    UDataMemory* sprepData;
+    const UBiDiProps *bdp; /* used only if checkBiDi is set */
+    int32_t refCount;
+    UBool isDataLoaded;
+    UBool doNFKC;
+    UBool checkBiDi;
+};
+
+/**
+ * Helper function for populating the UParseError struct
+ * @internal
+ */
+U_CAPI void U_EXPORT2
+uprv_syntaxError(const UChar* rules, 
+                 int32_t pos,
+                 int32_t rulesLen,
+                 UParseError* parseError);
+
+
+/**
+ * Swap StringPrep .spp profile data. See udataswp.h.
+ * @internal
+ */
+U_CAPI int32_t U_EXPORT2
+usprep_swap(const UDataSwapper *ds,
+            const void *inData, int32_t length, void *outData,
+            UErrorCode *pErrorCode);
+
+#endif /* #if !UCONFIG_NO_IDNA */
+
+#endif
+
+/*
+ * Hey, Emacs, please set the following:
+ *
+ * Local Variables:
+ * indent-tabs-mode: nil
+ * End:
+ *
+ */
diff --git a/icu/source/common/stringpiece.cpp b/icu/source/common/stringpiece.cpp
new file mode 100644
index 0000000..851a49a
--- /dev/null
+++ b/icu/source/common/stringpiece.cpp
@@ -0,0 +1,78 @@
+// Copyright (C) 2009-2010, International Business Machines
+// Corporation and others. All Rights Reserved.
+//
+// Copyright 2004 and onwards Google Inc.
+//
+// Author: wilsonh@google.com (Wilson Hsieh)
+//
+
+#include "unicode/utypes.h"
+#include "unicode/stringpiece.h"
+#include "cstring.h"
+#include "cmemory.h"
+
+U_NAMESPACE_BEGIN
+
+StringPiece::StringPiece(const char* str)
+    : ptr_(str), length_((str == NULL) ? 0 : static_cast<int32_t>(uprv_strlen(str))) { }
+
+StringPiece::StringPiece(const StringPiece& x, int32_t pos) {
+  if (pos < 0) {
+    pos = 0;
+  } else if (pos > x.length_) {
+    pos = x.length_;
+  }
+  ptr_ = x.ptr_ + pos;
+  length_ = x.length_ - pos;
+}
+
+StringPiece::StringPiece(const StringPiece& x, int32_t pos, int32_t len) {
+  if (pos < 0) {
+    pos = 0;
+  } else if (pos > x.length_) {
+    pos = x.length_;
+  }
+  if (len < 0) {
+    len = 0;
+  } else if (len > x.length_ - pos) {
+    len = x.length_ - pos;
+  }
+  ptr_ = x.ptr_ + pos;
+  length_ = len;
+}
+
+void StringPiece::set(const char* str) {
+  ptr_ = str;
+  if (str != NULL)
+    length_ = static_cast<int32_t>(uprv_strlen(str));
+  else
+    length_ = 0;
+}
+
+U_EXPORT UBool U_EXPORT2
+operator==(const StringPiece& x, const StringPiece& y) {
+  int32_t len = x.size();
+  if (len != y.size()) {
+    return false;
+  }
+  const char* p = x.data();
+  const char* p2 = y.data();
+  // Test last byte in case strings share large common prefix
+  if ((len > 0) && (p[len-1] != p2[len-1])) return false;
+  // At this point we can, but don't have to, ignore the last byte.
+  return uprv_memcmp(p, p2, len-1) == 0;
+}
+
+
+/* Microsft Visual Studios <= 8.0 complains about redefinition of this
+ * static const class variable. However, the C++ standard states that this 
+ * definition is correct. Perhaps there is a bug in the Microsoft compiler. 
+ * This is not an issue on any other compilers (that we know of) including 
+ * Visual Studios 9.0.
+ * Cygwin with MSVC 9.0 also complains here about redefinition.
+ */
+#if (!defined(_MSC_VER) || (_MSC_VER >= 1500)) && !defined(CYGWINMSVC)
+const int32_t StringPiece::npos;
+#endif
+
+U_NAMESPACE_END
diff --git a/icu/source/common/triedict.cpp b/icu/source/common/triedict.cpp
new file mode 100644
index 0000000..0dbb566
--- /dev/null
+++ b/icu/source/common/triedict.cpp
@@ -0,0 +1,1408 @@
+/**
+ *******************************************************************************
+ * Copyright (C) 2006-2008, International Business Machines Corporation        *
+ * and others. All Rights Reserved.                                            *
+ *******************************************************************************
+ */
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "triedict.h"
+#include "unicode/chariter.h"
+#include "unicode/uchriter.h"
+#include "unicode/strenum.h"
+#include "unicode/uenum.h"
+#include "unicode/udata.h"
+#include "cmemory.h"
+#include "udataswp.h"
+#include "uvector.h"
+#include "uvectr32.h"
+#include "uarrsort.h"
+
+//#define DEBUG_TRIE_DICT 1
+
+#ifdef DEBUG_TRIE_DICT
+#include <sys/times.h>
+#include <limits.h>
+#include <stdio.h>
+#endif
+
+U_NAMESPACE_BEGIN
+
+/*******************************************************************
+ * TrieWordDictionary
+ */
+
+TrieWordDictionary::TrieWordDictionary() {
+}
+
+TrieWordDictionary::~TrieWordDictionary() {
+}
+
+/*******************************************************************
+ * MutableTrieDictionary
+ */
+
+// Node structure for the ternary, uncompressed trie
+struct TernaryNode : public UMemory {
+    UChar       ch;         // UTF-16 code unit
+    uint16_t    flags;      // Flag word
+    TernaryNode *low;       // Less-than link
+    TernaryNode *equal;     // Equal link
+    TernaryNode *high;      // Greater-than link
+
+    TernaryNode(UChar uc);
+    ~TernaryNode();
+};
+
+enum MutableTrieNodeFlags {
+    kEndsWord = 0x0001      // This node marks the end of a valid word
+};
+
+inline
+TernaryNode::TernaryNode(UChar uc) {
+    ch = uc;
+    flags = 0;
+    low = NULL;
+    equal = NULL;
+    high = NULL;
+}
+
+// Not inline since it's recursive
+TernaryNode::~TernaryNode() {
+    delete low;
+    delete equal;
+    delete high;
+}
+
+MutableTrieDictionary::MutableTrieDictionary( UChar median, UErrorCode &status ) {
+    // Start the trie off with something. Having the root node already present
+    // cuts a special case out of the search/insertion functions.
+    // Making it a median character cuts the worse case for searches from
+    // 4x a balanced trie to 2x a balanced trie. It's best to choose something
+    // that starts a word that is midway in the list.
+    fTrie = new TernaryNode(median);
+    if (fTrie == NULL) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+    }
+    fIter = utext_openUChars(NULL, NULL, 0, &status);
+    if (U_SUCCESS(status) && fIter == NULL) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+    }
+}
+
+MutableTrieDictionary::MutableTrieDictionary( UErrorCode &status ) {
+    fTrie = NULL;
+    fIter = utext_openUChars(NULL, NULL, 0, &status);
+    if (U_SUCCESS(status) && fIter == NULL) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+    }
+}
+
+MutableTrieDictionary::~MutableTrieDictionary() {
+    delete fTrie;
+    utext_close(fIter);
+}
+
+int32_t
+MutableTrieDictionary::search( UText *text,
+                                   int32_t maxLength,
+                                   int32_t *lengths,
+                                   int &count,
+                                   int limit,
+                                   TernaryNode *&parent,
+                                   UBool &pMatched ) const {
+    // TODO: current implementation works in UTF-16 space
+    const TernaryNode *up = NULL;
+    const TernaryNode *p = fTrie;
+    int mycount = 0;
+    pMatched = TRUE;
+    int i;
+
+    UChar uc = utext_current32(text);
+    for (i = 0; i < maxLength && p != NULL; ++i) {
+        while (p != NULL) {
+            if (uc < p->ch) {
+                up = p;
+                p = p->low;
+            }
+            else if (uc == p->ch) {
+                break;
+            }
+            else {
+                up = p;
+                p = p->high;
+            }
+        }
+        if (p == NULL) {
+            pMatched = FALSE;
+            break;
+        }
+        // Must be equal to get here
+        if (limit > 0 && (p->flags & kEndsWord)) {
+            lengths[mycount++] = i+1;
+            --limit;
+        }
+        up = p;
+        p = p->equal;
+        uc = utext_next32(text);
+        uc = utext_current32(text);
+    }
+    
+    // Note that there is no way to reach here with up == 0 unless
+    // maxLength is 0 coming in.
+    parent = (TernaryNode *)up;
+    count = mycount;
+    return i;
+}
+
+void
+MutableTrieDictionary::addWord( const UChar *word,
+                                int32_t length,
+                                UErrorCode &status ) {
+#if 0
+    if (length <= 0) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+#endif
+    TernaryNode *parent;
+    UBool pMatched;
+    int count;
+    fIter = utext_openUChars(fIter, word, length, &status);
+    
+    int matched;
+    matched = search(fIter, length, NULL, count, 0, parent, pMatched);
+    
+    while (matched++ < length) {
+        UChar32 uc = utext_next32(fIter);  // TODO:  supplemetary support?
+        U_ASSERT(uc != U_SENTINEL);
+        TernaryNode *newNode = new TernaryNode(uc);
+        if (newNode == NULL) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+        if (pMatched) {
+            parent->equal = newNode;
+        }
+        else {
+            pMatched = TRUE;
+            if (uc < parent->ch) {
+                parent->low = newNode;
+            }
+            else {
+                parent->high = newNode;
+            }
+        }
+        parent = newNode;
+    }
+
+    parent->flags |= kEndsWord;
+}
+
+#if 0
+void
+MutableTrieDictionary::addWords( UEnumeration *words,
+                                  UErrorCode &status ) {
+    int32_t length;
+    const UChar *word;
+    while ((word = uenum_unext(words, &length, &status)) && U_SUCCESS(status)) {
+        addWord(word, length, status);
+    }
+}
+#endif
+
+int32_t
+MutableTrieDictionary::matches( UText *text,
+                                int32_t maxLength,
+                                int32_t *lengths,
+                                int &count,
+                                int limit ) const {
+    TernaryNode *parent;
+    UBool pMatched;
+    return search(text, maxLength, lengths, count, limit, parent, pMatched);
+}
+
+// Implementation of iteration for MutableTrieDictionary
+class MutableTrieEnumeration : public StringEnumeration {
+private:
+    UStack      fNodeStack;     // Stack of nodes to process
+    UVector32   fBranchStack;   // Stack of which branch we are working on
+    TernaryNode *fRoot;         // Root node
+    enum StackBranch {
+        kLessThan,
+        kEqual,
+        kGreaterThan,
+        kDone
+    };
+
+public:
+    static UClassID U_EXPORT2 getStaticClassID(void);
+    virtual UClassID getDynamicClassID(void) const;
+public:
+    MutableTrieEnumeration(TernaryNode *root, UErrorCode &status) 
+        : fNodeStack(status), fBranchStack(status) {
+        fRoot = root;
+        fNodeStack.push(root, status);
+        fBranchStack.push(kLessThan, status);
+        unistr.remove();
+    }
+    
+    virtual ~MutableTrieEnumeration() {
+    }
+    
+    virtual StringEnumeration *clone() const {
+        UErrorCode status = U_ZERO_ERROR;
+        return new MutableTrieEnumeration(fRoot, status);
+    }
+    
+    virtual const UnicodeString *snext(UErrorCode &status) {
+        if (fNodeStack.empty() || U_FAILURE(status)) {
+            return NULL;
+        }
+        TernaryNode *node = (TernaryNode *) fNodeStack.peek();
+        StackBranch where = (StackBranch) fBranchStack.peeki();
+        while (!fNodeStack.empty() && U_SUCCESS(status)) {
+            UBool emit;
+            UBool equal;
+
+            switch (where) {
+            case kLessThan:
+                if (node->low != NULL) {
+                    fBranchStack.setElementAt(kEqual, fBranchStack.size()-1);
+                    node = (TernaryNode *) fNodeStack.push(node->low, status);
+                    where = (StackBranch) fBranchStack.push(kLessThan, status);
+                    break;
+                }
+            case kEqual:
+                emit = (node->flags & kEndsWord) != 0;
+                equal = (node->equal != NULL);
+                // If this node should be part of the next emitted string, append
+                // the UChar to the string, and make sure we pop it when we come
+                // back to this node. The character should only be in the string
+                // for as long as we're traversing the equal subtree of this node
+                if (equal || emit) {
+                    unistr.append(node->ch);
+                    fBranchStack.setElementAt(kGreaterThan, fBranchStack.size()-1);
+                }
+                if (equal) {
+                    node = (TernaryNode *) fNodeStack.push(node->equal, status);
+                    where = (StackBranch) fBranchStack.push(kLessThan, status);
+                }
+                if (emit) {
+                    return &unistr;
+                }
+                if (equal) {
+                    break;
+                }
+            case kGreaterThan:
+                // If this node's character is in the string, remove it.
+                if (node->equal != NULL || (node->flags & kEndsWord)) {
+                    unistr.truncate(unistr.length()-1);
+                }
+                if (node->high != NULL) {
+                    fBranchStack.setElementAt(kDone, fBranchStack.size()-1);
+                    node = (TernaryNode *) fNodeStack.push(node->high, status);
+                    where = (StackBranch) fBranchStack.push(kLessThan, status);
+                    break;
+                }
+            case kDone:
+                fNodeStack.pop();
+                fBranchStack.popi();
+                node = (TernaryNode *) fNodeStack.peek();
+                where = (StackBranch) fBranchStack.peeki();
+                break;
+            default:
+                return NULL;
+            }
+        }
+        return NULL;
+    }
+    
+    // Very expensive, but this should never be used.
+    virtual int32_t count(UErrorCode &status) const {
+        MutableTrieEnumeration counter(fRoot, status);
+        int32_t result = 0;
+        while (counter.snext(status) != NULL && U_SUCCESS(status)) {
+            ++result;
+        }
+        return result;
+    }
+    
+    virtual void reset(UErrorCode &status) {
+        fNodeStack.removeAllElements();
+        fBranchStack.removeAllElements();
+        fNodeStack.push(fRoot, status);
+        fBranchStack.push(kLessThan, status);
+        unistr.remove();
+    }
+};
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(MutableTrieEnumeration)
+
+StringEnumeration *
+MutableTrieDictionary::openWords( UErrorCode &status ) const {
+    if (U_FAILURE(status)) {
+        return NULL;
+    }
+    return new MutableTrieEnumeration(fTrie, status);
+}
+
+/*******************************************************************
+ * CompactTrieDictionary
+ */
+
+struct CompactTrieHeader {
+    uint32_t        size;           // Size of the data in bytes
+    uint32_t        magic;          // Magic number (including version)
+    uint16_t        nodeCount;      // Number of entries in offsets[]
+    uint16_t        root;           // Node number of the root node
+    uint32_t        offsets[1];      // Offsets to nodes from start of data
+};
+
+// Note that to avoid platform-specific alignment issues, all members of the node
+// structures should be the same size, or should contain explicit padding to
+// natural alignment boundaries.
+
+// We can't use a bitfield for the flags+count field, because the layout of those
+// is not portable. 12 bits of count allows for up to 4096 entries in a node.
+struct CompactTrieNode {
+    uint16_t        flagscount;     // Count of sub-entries, plus flags
+};
+
+enum CompactTrieNodeFlags {
+    kVerticalNode   = 0x1000,       // This is a vertical node
+    kParentEndsWord = 0x2000,       // The node whose equal link points to this ends a word
+    kReservedFlag1  = 0x4000,
+    kReservedFlag2  = 0x8000,
+    kCountMask      = 0x0FFF,       // The count portion of flagscount
+    kFlagMask       = 0xF000        // The flags portion of flagscount
+};
+
+// The two node types are distinguished by the kVerticalNode flag.
+
+struct CompactTrieHorizontalEntry {
+    uint16_t        ch;             // UChar
+    uint16_t        equal;          // Equal link node index
+};
+
+// We don't use inheritance here because C++ does not guarantee that the
+// base class comes first in memory!!
+
+struct CompactTrieHorizontalNode {
+    uint16_t        flagscount;     // Count of sub-entries, plus flags
+    CompactTrieHorizontalEntry      entries[1];
+};
+
+struct CompactTrieVerticalNode {
+    uint16_t        flagscount;     // Count of sub-entries, plus flags
+    uint16_t        equal;          // Equal link node index
+    uint16_t        chars[1];       // Code units
+};
+
+// {'Dic', 1}, version 1
+#define COMPACT_TRIE_MAGIC_1 0x44696301
+
+CompactTrieDictionary::CompactTrieDictionary(UDataMemory *dataObj,
+                                                UErrorCode &status )
+: fUData(dataObj)
+{
+    fData = (const CompactTrieHeader *) udata_getMemory(dataObj);
+    fOwnData = FALSE;
+    if (fData->magic != COMPACT_TRIE_MAGIC_1) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        fData = NULL;
+    }
+}
+CompactTrieDictionary::CompactTrieDictionary( const void *data,
+                                                UErrorCode &status )
+: fUData(NULL)
+{
+    fData = (const CompactTrieHeader *) data;
+    fOwnData = FALSE;
+    if (fData->magic != COMPACT_TRIE_MAGIC_1) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        fData = NULL;
+    }
+}
+
+CompactTrieDictionary::CompactTrieDictionary( const MutableTrieDictionary &dict,
+                                                UErrorCode &status )
+: fUData(NULL)
+{
+    fData = compactMutableTrieDictionary(dict, status);
+    fOwnData = !U_FAILURE(status);
+}
+
+CompactTrieDictionary::~CompactTrieDictionary() {
+    if (fOwnData) {
+        uprv_free((void *)fData);
+    }
+    if (fUData) {
+        udata_close(fUData);
+    }
+}
+
+uint32_t
+CompactTrieDictionary::dataSize() const {
+    return fData->size;
+}
+
+const void *
+CompactTrieDictionary::data() const {
+    return fData;
+}
+
+// This function finds the address of a node for us, given its node ID
+static inline const CompactTrieNode *
+getCompactNode(const CompactTrieHeader *header, uint16_t node) {
+    return (const CompactTrieNode *)((const uint8_t *)header + header->offsets[node]);
+}
+
+int32_t
+CompactTrieDictionary::matches( UText *text,
+                                int32_t maxLength,
+                                int32_t *lengths,
+                                int &count,
+                                int limit ) const {
+    // TODO: current implementation works in UTF-16 space
+    const CompactTrieNode *node = getCompactNode(fData, fData->root);
+    int mycount = 0;
+
+    UChar uc = utext_current32(text);
+    int i = 0;
+
+    while (node != NULL) {
+        // Check if the node we just exited ends a word
+        if (limit > 0 && (node->flagscount & kParentEndsWord)) {
+            lengths[mycount++] = i;
+            --limit;
+        }
+        // Check that we haven't exceeded the maximum number of input characters.
+        // We have to do that here rather than in the while condition so that
+        // we can check for ending a word, above.
+        if (i >= maxLength) {
+            break;
+        }
+
+        int nodeCount = (node->flagscount & kCountMask);
+        if (nodeCount == 0) {
+            // Special terminal node; return now
+            break;
+        }
+        if (node->flagscount & kVerticalNode) {
+            // Vertical node; check all the characters in it
+            const CompactTrieVerticalNode *vnode = (const CompactTrieVerticalNode *)node;
+            for (int j = 0; j < nodeCount && i < maxLength; ++j) {
+                if (uc != vnode->chars[j]) {
+                    // We hit a non-equal character; return
+                    goto exit;
+                }
+                utext_next32(text);
+                uc = utext_current32(text);
+                ++i;
+            }
+            // To get here we must have come through the whole list successfully;
+            // go on to the next node. Note that a word cannot end in the middle
+            // of a vertical node.
+            node = getCompactNode(fData, vnode->equal);
+        }
+        else {
+            // Horizontal node; do binary search
+            const CompactTrieHorizontalNode *hnode = (const CompactTrieHorizontalNode *)node;
+            int low = 0;
+            int high = nodeCount-1;
+            int middle;
+            node = NULL;    // If we don't find a match, we'll fall out of the loop
+            while (high >= low) {
+                middle = (high+low)/2;
+                if (uc == hnode->entries[middle].ch) {
+                    // We hit a match; get the next node and next character
+                    node = getCompactNode(fData, hnode->entries[middle].equal);
+                    utext_next32(text);
+                    uc = utext_current32(text);
+                    ++i;
+                    break;
+                }
+                else if (uc < hnode->entries[middle].ch) {
+                    high = middle-1;
+                }
+                else {
+                    low = middle+1;
+                }
+            }
+        }
+    }
+exit:
+    count = mycount;
+    return i;
+}
+
+// Implementation of iteration for CompactTrieDictionary
+class CompactTrieEnumeration : public StringEnumeration {
+private:
+    UVector32               fNodeStack;     // Stack of nodes to process
+    UVector32               fIndexStack;    // Stack of where in node we are
+    const CompactTrieHeader *fHeader;       // Trie data
+
+public:
+    static UClassID U_EXPORT2 getStaticClassID(void);
+    virtual UClassID getDynamicClassID(void) const;
+public:
+    CompactTrieEnumeration(const CompactTrieHeader *header, UErrorCode &status) 
+        : fNodeStack(status), fIndexStack(status) {
+        fHeader = header;
+        fNodeStack.push(header->root, status);
+        fIndexStack.push(0, status);
+        unistr.remove();
+    }
+    
+    virtual ~CompactTrieEnumeration() {
+    }
+    
+    virtual StringEnumeration *clone() const {
+        UErrorCode status = U_ZERO_ERROR;
+        return new CompactTrieEnumeration(fHeader, status);
+    }
+    
+    virtual const UnicodeString * snext(UErrorCode &status);
+
+    // Very expensive, but this should never be used.
+    virtual int32_t count(UErrorCode &status) const {
+        CompactTrieEnumeration counter(fHeader, status);
+        int32_t result = 0;
+        while (counter.snext(status) != NULL && U_SUCCESS(status)) {
+            ++result;
+        }
+        return result;
+    }
+    
+    virtual void reset(UErrorCode &status) {
+        fNodeStack.removeAllElements();
+        fIndexStack.removeAllElements();
+        fNodeStack.push(fHeader->root, status);
+        fIndexStack.push(0, status);
+        unistr.remove();
+    }
+};
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CompactTrieEnumeration)
+
+const UnicodeString *
+CompactTrieEnumeration::snext(UErrorCode &status) {
+    if (fNodeStack.empty() || U_FAILURE(status)) {
+        return NULL;
+    }
+    const CompactTrieNode *node = getCompactNode(fHeader, fNodeStack.peeki());
+    int where = fIndexStack.peeki();
+    while (!fNodeStack.empty() && U_SUCCESS(status)) {
+        int nodeCount = (node->flagscount & kCountMask);
+        UBool goingDown = FALSE;
+        if (nodeCount == 0) {
+            // Terminal node; go up immediately
+            fNodeStack.popi();
+            fIndexStack.popi();
+            node = getCompactNode(fHeader, fNodeStack.peeki());
+            where = fIndexStack.peeki();
+        }
+        else if (node->flagscount & kVerticalNode) {
+            // Vertical node
+            const CompactTrieVerticalNode *vnode = (const CompactTrieVerticalNode *)node;
+            if (where == 0) {
+                // Going down
+                unistr.append((const UChar *)vnode->chars, (int32_t) nodeCount);
+                fIndexStack.setElementAt(1, fIndexStack.size()-1);
+                node = getCompactNode(fHeader, fNodeStack.push(vnode->equal, status));
+                where = fIndexStack.push(0, status);
+                goingDown = TRUE;
+            }
+            else {
+                // Going up
+                unistr.truncate(unistr.length()-nodeCount);
+                fNodeStack.popi();
+                fIndexStack.popi();
+                node = getCompactNode(fHeader, fNodeStack.peeki());
+                where = fIndexStack.peeki();
+            }
+        }
+        else {
+            // Horizontal node
+            const CompactTrieHorizontalNode *hnode = (const CompactTrieHorizontalNode *)node;
+            if (where > 0) {
+                // Pop previous char
+                unistr.truncate(unistr.length()-1);
+            }
+            if (where < nodeCount) {
+                // Push on next node
+                unistr.append((UChar)hnode->entries[where].ch);
+                fIndexStack.setElementAt(where+1, fIndexStack.size()-1);
+                node = getCompactNode(fHeader, fNodeStack.push(hnode->entries[where].equal, status));
+                where = fIndexStack.push(0, status);
+                goingDown = TRUE;
+            }
+            else {
+                // Going up
+                fNodeStack.popi();
+                fIndexStack.popi();
+                node = getCompactNode(fHeader, fNodeStack.peeki());
+                where = fIndexStack.peeki();
+            }
+        }
+        // Check if the parent of the node we've just gone down to ends a
+        // word. If so, return it.
+        if (goingDown && (node->flagscount & kParentEndsWord)) {
+            return &unistr;
+        }
+    }
+    return NULL;
+}
+
+StringEnumeration *
+CompactTrieDictionary::openWords( UErrorCode &status ) const {
+    if (U_FAILURE(status)) {
+        return NULL;
+    }
+    return new CompactTrieEnumeration(fData, status);
+}
+
+//
+// Below here is all code related to converting a ternary trie to a compact trie
+// and back again
+//
+
+// Helper classes to construct the compact trie
+class BuildCompactTrieNode: public UMemory {
+ public:
+    UBool           fParentEndsWord;
+    UBool           fVertical;
+    UBool           fHasDuplicate;
+    int32_t         fNodeID;
+    UnicodeString   fChars;
+
+ public:
+    BuildCompactTrieNode(UBool parentEndsWord, UBool vertical, UStack &nodes, UErrorCode &status) {
+        fParentEndsWord = parentEndsWord;
+        fHasDuplicate = FALSE;
+        fVertical = vertical;
+        fNodeID = nodes.size();
+        nodes.push(this, status);
+    }
+    
+    virtual ~BuildCompactTrieNode() {
+    }
+    
+    virtual uint32_t size() {
+        return sizeof(uint16_t);
+    }
+    
+    virtual void write(uint8_t *bytes, uint32_t &offset, const UVector32 &/*translate*/) {
+        // Write flag/count
+        *((uint16_t *)(bytes+offset)) = (fChars.length() & kCountMask)
+            | (fVertical ? kVerticalNode : 0) | (fParentEndsWord ? kParentEndsWord : 0 );
+        offset += sizeof(uint16_t);
+    }
+};
+
+class BuildCompactTrieHorizontalNode: public BuildCompactTrieNode {
+ public:
+    UStack          fLinks;
+
+ public:
+    BuildCompactTrieHorizontalNode(UBool parentEndsWord, UStack &nodes, UErrorCode &status)
+        : BuildCompactTrieNode(parentEndsWord, FALSE, nodes, status), fLinks(status) {
+    }
+    
+    virtual ~BuildCompactTrieHorizontalNode() {
+    }
+    
+    virtual uint32_t size() {
+        return offsetof(CompactTrieHorizontalNode,entries) +
+                (fChars.length()*sizeof(CompactTrieHorizontalEntry));
+    }
+    
+    virtual void write(uint8_t *bytes, uint32_t &offset, const UVector32 &translate) {
+        BuildCompactTrieNode::write(bytes, offset, translate);
+        int32_t count = fChars.length();
+        for (int32_t i = 0; i < count; ++i) {
+            CompactTrieHorizontalEntry *entry = (CompactTrieHorizontalEntry *)(bytes+offset);
+            entry->ch = fChars[i];
+            entry->equal = translate.elementAti(((BuildCompactTrieNode *)fLinks[i])->fNodeID);
+#ifdef DEBUG_TRIE_DICT
+            if (entry->equal == 0) {
+                fprintf(stderr, "ERROR: horizontal link %d, logical node %d maps to physical node zero\n",
+                        i, ((BuildCompactTrieNode *)fLinks[i])->fNodeID);
+            }
+#endif
+            offset += sizeof(CompactTrieHorizontalEntry);
+        }
+    }
+    
+    void addNode(UChar ch, BuildCompactTrieNode *link, UErrorCode &status) {
+        fChars.append(ch);
+        fLinks.push(link, status);
+    }
+};
+
+class BuildCompactTrieVerticalNode: public BuildCompactTrieNode {
+ public:
+    BuildCompactTrieNode    *fEqual;
+
+ public:
+    BuildCompactTrieVerticalNode(UBool parentEndsWord, UStack &nodes, UErrorCode &status)
+        : BuildCompactTrieNode(parentEndsWord, TRUE, nodes, status) {
+        fEqual = NULL;
+    }
+    
+    virtual ~BuildCompactTrieVerticalNode() {
+    }
+    
+    virtual uint32_t size() {
+        return offsetof(CompactTrieVerticalNode,chars) + (fChars.length()*sizeof(uint16_t));
+    }
+    
+    virtual void write(uint8_t *bytes, uint32_t &offset, const UVector32 &translate) {
+        CompactTrieVerticalNode *node = (CompactTrieVerticalNode *)(bytes+offset);
+        BuildCompactTrieNode::write(bytes, offset, translate);
+        node->equal = translate.elementAti(fEqual->fNodeID);
+        offset += sizeof(node->equal);
+#ifdef DEBUG_TRIE_DICT
+        if (node->equal == 0) {
+            fprintf(stderr, "ERROR: vertical link, logical node %d maps to physical node zero\n",
+                    fEqual->fNodeID);
+        }
+#endif
+        fChars.extract(0, fChars.length(), (UChar *)node->chars);
+        offset += sizeof(uint16_t)*fChars.length();
+    }
+    
+    void addChar(UChar ch) {
+        fChars.append(ch);
+    }
+    
+    void setLink(BuildCompactTrieNode *node) {
+        fEqual = node;
+    }
+};
+
+// Forward declaration
+static void walkHorizontal(const TernaryNode *node,
+                            BuildCompactTrieHorizontalNode *building,
+                            UStack &nodes,
+                            UErrorCode &status);
+
+// Convert one node. Uses recursion.
+
+static BuildCompactTrieNode *
+compactOneNode(const TernaryNode *node, UBool parentEndsWord, UStack &nodes, UErrorCode &status) {
+    if (U_FAILURE(status)) {
+        return NULL;
+    }
+    BuildCompactTrieNode *result = NULL;
+    UBool horizontal = (node->low != NULL || node->high != NULL);
+    if (horizontal) {
+        BuildCompactTrieHorizontalNode *hResult =
+                new BuildCompactTrieHorizontalNode(parentEndsWord, nodes, status);
+        if (hResult == NULL) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            return NULL;
+        }
+        if (U_SUCCESS(status)) {
+            walkHorizontal(node, hResult, nodes, status);
+            result = hResult;
+        }
+    }
+    else {
+        BuildCompactTrieVerticalNode *vResult =
+                new BuildCompactTrieVerticalNode(parentEndsWord, nodes, status);
+        if (vResult == NULL) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+        }
+        else if (U_SUCCESS(status)) {
+            UBool   endsWord = FALSE;
+            // Take up nodes until we end a word, or hit a node with < or > links
+            do {
+                vResult->addChar(node->ch);
+                endsWord = (node->flags & kEndsWord) != 0;
+                node = node->equal;
+            }
+            while(node != NULL && !endsWord && node->low == NULL && node->high == NULL);
+            if (node == NULL) {
+                if (!endsWord) {
+                    status = U_ILLEGAL_ARGUMENT_ERROR;  // Corrupt input trie
+                }
+                else {
+                    vResult->setLink((BuildCompactTrieNode *)nodes[1]);
+                }
+            }
+            else {
+                vResult->setLink(compactOneNode(node, endsWord, nodes, status));
+            }
+            result = vResult;
+        }
+    }
+    return result;
+}
+
+// Walk the set of peers at the same level, to build a horizontal node.
+// Uses recursion.
+
+static void walkHorizontal(const TernaryNode *node,
+                            BuildCompactTrieHorizontalNode *building,
+                            UStack &nodes,
+                            UErrorCode &status) {
+    while (U_SUCCESS(status) && node != NULL) {
+        if (node->low != NULL) {
+            walkHorizontal(node->low, building, nodes, status);
+        }
+        BuildCompactTrieNode *link = NULL;
+        if (node->equal != NULL) {
+            link = compactOneNode(node->equal, (node->flags & kEndsWord) != 0, nodes, status);
+        }
+        else if (node->flags & kEndsWord) {
+            link = (BuildCompactTrieNode *)nodes[1];
+        }
+        if (U_SUCCESS(status) && link != NULL) {
+            building->addNode(node->ch, link, status);
+        }
+        // Tail recurse manually instead of leaving it to the compiler.
+        //if (node->high != NULL) {
+        //    walkHorizontal(node->high, building, nodes, status);
+        //}
+        node = node->high;
+    }
+}
+
+U_NAMESPACE_END
+U_NAMESPACE_USE
+U_CDECL_BEGIN
+static int32_t U_CALLCONV
+_sortBuildNodes(const void * /*context*/, const void *voidl, const void *voidr) {
+    BuildCompactTrieNode *left = *(BuildCompactTrieNode **)voidl;
+    BuildCompactTrieNode *right = *(BuildCompactTrieNode **)voidr;
+    // Check for comparing a node to itself, to avoid spurious duplicates
+    if (left == right) {
+        return 0;
+    }
+    // Most significant is type of node. Can never coalesce.
+    if (left->fVertical != right->fVertical) {
+        return left->fVertical - right->fVertical;
+    }
+    // Next, the "parent ends word" flag. If that differs, we cannot coalesce.
+    if (left->fParentEndsWord != right->fParentEndsWord) {
+        return left->fParentEndsWord - right->fParentEndsWord;
+    }
+    // Next, the string. If that differs, we can never coalesce.
+    int32_t result = left->fChars.compare(right->fChars);
+    if (result != 0) {
+        return result;
+    }
+    // We know they're both the same node type, so branch for the two cases.
+    if (left->fVertical) {
+        result = ((BuildCompactTrieVerticalNode *)left)->fEqual->fNodeID
+                            - ((BuildCompactTrieVerticalNode *)right)->fEqual->fNodeID;
+    }
+    else {
+        // We need to compare the links vectors. They should be the
+        // same size because the strings were equal.
+        // We compare the node IDs instead of the pointers, to handle
+        // coalesced nodes.
+        BuildCompactTrieHorizontalNode *hleft, *hright;
+        hleft = (BuildCompactTrieHorizontalNode *)left;
+        hright = (BuildCompactTrieHorizontalNode *)right;
+        int32_t count = hleft->fLinks.size();
+        for (int32_t i = 0; i < count && result == 0; ++i) {
+            result = ((BuildCompactTrieNode *)(hleft->fLinks[i]))->fNodeID -
+                     ((BuildCompactTrieNode *)(hright->fLinks[i]))->fNodeID;
+        }
+    }
+    // If they are equal to each other, mark them (speeds coalescing)
+    if (result == 0) {
+        left->fHasDuplicate = TRUE;
+        right->fHasDuplicate = TRUE;
+    }
+    return result;
+}
+U_CDECL_END
+U_NAMESPACE_BEGIN
+
+static void coalesceDuplicates(UStack &nodes, UErrorCode &status) {
+    // We sort the array of nodes to place duplicates next to each other
+    if (U_FAILURE(status)) {
+        return;
+    }
+    int32_t size = nodes.size();
+    void **array = (void **)uprv_malloc(sizeof(void *)*size);
+    if (array == NULL) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    (void) nodes.toArray(array);
+    
+    // Now repeatedly identify duplicates until there are no more
+    int32_t dupes = 0;
+    long    passCount = 0;
+#ifdef DEBUG_TRIE_DICT
+    long    totalDupes = 0;
+#endif
+    do {
+        BuildCompactTrieNode *node;
+        BuildCompactTrieNode *first = NULL;
+        BuildCompactTrieNode **p;
+        BuildCompactTrieNode **pFirst = NULL;
+        int32_t counter = size - 2;
+        // Sort the array, skipping nodes 0 and 1. Use quicksort for the first
+        // pass for speed. For the second and subsequent passes, we use stable
+        // (insertion) sort for two reasons:
+        // 1. The array is already mostly ordered, so we get better performance.
+        // 2. The way we find one and only one instance of a set of duplicates is to
+        //    check that the node ID equals the array index. If we used an unstable
+        //    sort for the second or later passes, it's possible that none of the
+        //    duplicates would wind up with a node ID equal to its array index.
+        //    The sort stability guarantees that, because as we coalesce more and
+        //    more groups, the first element of the resultant group will be one of
+        //    the first elements of the groups being coalesced.
+        // To use quicksort for the second and subsequent passes, we would have to
+        // find the minimum of the node numbers in a group, and set all the nodes
+        // in the group to that node number.
+        uprv_sortArray(array+2, counter, sizeof(void *), _sortBuildNodes, NULL, (passCount > 0), &status);
+        dupes = 0;
+        for (p = (BuildCompactTrieNode **)array + 2; counter > 0; --counter, ++p) {
+            node = *p;
+            if (node->fHasDuplicate) {
+                if (first == NULL) {
+                    first = node;
+                    pFirst = p;
+                }
+                else if (_sortBuildNodes(NULL, pFirst, p) != 0) {
+                    // Starting a new run of dupes
+                    first = node;
+                    pFirst = p;
+                }
+                else if (node->fNodeID != first->fNodeID) {
+                    // Slave one to the other, note duplicate
+                    node->fNodeID = first->fNodeID;
+                    dupes += 1;
+                }
+            }
+            else {
+                // This node has no dupes
+                first = NULL;
+                pFirst = NULL;
+            }
+        }
+        passCount += 1;
+#ifdef DEBUG_TRIE_DICT
+        totalDupes += dupes;
+        fprintf(stderr, "Trie node dupe removal, pass %d: %d nodes tagged\n", passCount, dupes);
+#endif
+    }
+    while (dupes > 0);
+#ifdef DEBUG_TRIE_DICT
+    fprintf(stderr, "Trie node dupe removal complete: %d tagged in %d passes\n", totalDupes, passCount);
+#endif
+
+    // We no longer need the temporary array, as the nodes have all been marked appropriately.
+    uprv_free(array);
+}
+
+U_NAMESPACE_END
+U_CDECL_BEGIN
+static void U_CALLCONV _deleteBuildNode(void *obj) {
+    delete (BuildCompactTrieNode *) obj;
+}
+U_CDECL_END
+U_NAMESPACE_BEGIN
+
+CompactTrieHeader *
+CompactTrieDictionary::compactMutableTrieDictionary( const MutableTrieDictionary &dict,
+                                UErrorCode &status ) {
+    if (U_FAILURE(status)) {
+        return NULL;
+    }
+#ifdef DEBUG_TRIE_DICT
+    struct tms timing;
+    struct tms previous;
+    (void) ::times(&previous);
+#endif
+    UStack nodes(_deleteBuildNode, NULL, status);      // Index of nodes
+
+    // Add node 0, used as the NULL pointer/sentinel.
+    nodes.addElement((int32_t)0, status);
+
+    // Start by creating the special empty node we use to indicate that the parent
+    // terminates a word. This must be node 1, because the builder assumes
+    // that.
+    if (U_FAILURE(status)) {
+        return NULL;
+    }
+    BuildCompactTrieNode *terminal = new BuildCompactTrieNode(TRUE, FALSE, nodes, status);
+    if (terminal == NULL) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+    }
+
+    // This call does all the work of building the new trie structure. The root
+    // will be node 2.
+    BuildCompactTrieNode *root = compactOneNode(dict.fTrie, FALSE, nodes, status);
+#ifdef DEBUG_TRIE_DICT
+    (void) ::times(&timing);
+    fprintf(stderr, "Compact trie built, %d nodes, time user %f system %f\n",
+        nodes.size(), (double)(timing.tms_utime-previous.tms_utime)/CLK_TCK,
+        (double)(timing.tms_stime-previous.tms_stime)/CLK_TCK);
+    previous = timing;
+#endif
+
+    // Now coalesce all duplicate nodes.
+    coalesceDuplicates(nodes, status);
+#ifdef DEBUG_TRIE_DICT
+    (void) ::times(&timing);
+    fprintf(stderr, "Duplicates coalesced, time user %f system %f\n",
+        (double)(timing.tms_utime-previous.tms_utime)/CLK_TCK,
+        (double)(timing.tms_stime-previous.tms_stime)/CLK_TCK);
+    previous = timing;
+#endif
+
+    // Next, build the output trie.
+    // First we compute all the sizes and build the node ID translation table.
+    uint32_t totalSize = offsetof(CompactTrieHeader,offsets);
+    int32_t count = nodes.size();
+    int32_t nodeCount = 1;              // The sentinel node we already have
+    BuildCompactTrieNode *node;
+    int32_t i;
+    UVector32 translate(count, status); // Should be no growth needed after this
+    translate.push(0, status);          // The sentinel node
+    
+    if (U_FAILURE(status)) {
+        return NULL;
+    }
+
+    for (i = 1; i < count; ++i) {
+        node = (BuildCompactTrieNode *)nodes[i];
+        if (node->fNodeID == i) {
+            // Only one node out of each duplicate set is used
+            if (i >= translate.size()) {
+                // Logically extend the mapping table
+                translate.setSize(i+1);
+            }
+            translate.setElementAt(nodeCount++, i);
+            totalSize += node->size();
+        }
+    }
+    
+    // Check for overflowing 16 bits worth of nodes.
+    if (nodeCount > 0x10000) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return NULL;
+    }
+    
+    // Add enough room for the offsets.
+    totalSize += nodeCount*sizeof(uint32_t);
+#ifdef DEBUG_TRIE_DICT
+    (void) ::times(&timing);
+    fprintf(stderr, "Sizes/mapping done, time user %f system %f\n",
+        (double)(timing.tms_utime-previous.tms_utime)/CLK_TCK,
+        (double)(timing.tms_stime-previous.tms_stime)/CLK_TCK);
+    previous = timing;
+    fprintf(stderr, "%d nodes, %d unique, %d bytes\n", nodes.size(), nodeCount, totalSize);
+#endif
+    uint8_t *bytes = (uint8_t *)uprv_malloc(totalSize);
+    if (bytes == NULL) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
+    }
+
+    CompactTrieHeader *header = (CompactTrieHeader *)bytes;
+    header->size = totalSize;
+    header->nodeCount = nodeCount;
+    header->offsets[0] = 0;                     // Sentinel
+    header->root = translate.elementAti(root->fNodeID);
+#ifdef DEBUG_TRIE_DICT
+    if (header->root == 0) {
+        fprintf(stderr, "ERROR: root node %d translate to physical zero\n", root->fNodeID);
+    }
+#endif
+    uint32_t offset = offsetof(CompactTrieHeader,offsets)+(nodeCount*sizeof(uint32_t));
+    nodeCount = 1;
+    // Now write the data
+    for (i = 1; i < count; ++i) {
+        node = (BuildCompactTrieNode *)nodes[i];
+        if (node->fNodeID == i) {
+            header->offsets[nodeCount++] = offset;
+            node->write(bytes, offset, translate);
+        }
+    }
+#ifdef DEBUG_TRIE_DICT
+    (void) ::times(&timing);
+    fprintf(stderr, "Trie built, time user %f system %f\n",
+        (double)(timing.tms_utime-previous.tms_utime)/CLK_TCK,
+        (double)(timing.tms_stime-previous.tms_stime)/CLK_TCK);
+    previous = timing;
+    fprintf(stderr, "Final offset is %d\n", offset);
+    
+    // Collect statistics on node types and sizes
+    int hCount = 0;
+    int vCount = 0;
+    size_t hSize = 0;
+    size_t vSize = 0;
+    size_t hItemCount = 0;
+    size_t vItemCount = 0;
+    uint32_t previousOff = offset;
+    for (uint16_t nodeIdx = nodeCount-1; nodeIdx >= 2; --nodeIdx) {
+        const CompactTrieNode *node = getCompactNode(header, nodeIdx);
+        if (node->flagscount & kVerticalNode) {
+            vCount += 1;
+            vItemCount += (node->flagscount & kCountMask);
+            vSize += previousOff-header->offsets[nodeIdx];
+        }
+        else {
+            hCount += 1;
+            hItemCount += (node->flagscount & kCountMask);
+            hSize += previousOff-header->offsets[nodeIdx];
+        }
+        previousOff = header->offsets[nodeIdx];
+    }
+    fprintf(stderr, "Horizontal nodes: %d total, average %f bytes with %f items\n", hCount,
+                (double)hSize/hCount, (double)hItemCount/hCount);
+    fprintf(stderr, "Vertical nodes: %d total, average %f bytes with %f items\n", vCount,
+                (double)vSize/vCount, (double)vItemCount/vCount);
+#endif
+
+    if (U_FAILURE(status)) {
+        uprv_free(bytes);
+        header = NULL;
+    }
+    else {
+        header->magic = COMPACT_TRIE_MAGIC_1;
+    }
+    return header;
+}
+
+// Forward declaration
+static TernaryNode *
+unpackOneNode( const CompactTrieHeader *header, const CompactTrieNode *node, UErrorCode &status );
+
+
+// Convert a horizontal node (or subarray thereof) into a ternary subtrie
+static TernaryNode *
+unpackHorizontalArray( const CompactTrieHeader *header, const CompactTrieHorizontalEntry *array,
+                            int low, int high, UErrorCode &status ) {
+    if (U_FAILURE(status) || low > high) {
+        return NULL;
+    }
+    int middle = (low+high)/2;
+    TernaryNode *result = new TernaryNode(array[middle].ch);
+    if (result == NULL) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
+    }
+    const CompactTrieNode *equal = getCompactNode(header, array[middle].equal);
+    if (equal->flagscount & kParentEndsWord) {
+        result->flags |= kEndsWord;
+    }
+    result->low = unpackHorizontalArray(header, array, low, middle-1, status);
+    result->high = unpackHorizontalArray(header, array, middle+1, high, status);
+    result->equal = unpackOneNode(header, equal, status);
+    return result;
+}                            
+
+// Convert one compact trie node into a ternary subtrie
+static TernaryNode *
+unpackOneNode( const CompactTrieHeader *header, const CompactTrieNode *node, UErrorCode &status ) {
+    int nodeCount = (node->flagscount & kCountMask);
+    if (nodeCount == 0 || U_FAILURE(status)) {
+        // Failure, or terminal node
+        return NULL;
+    }
+    if (node->flagscount & kVerticalNode) {
+        const CompactTrieVerticalNode *vnode = (const CompactTrieVerticalNode *)node;
+        TernaryNode *head = NULL;
+        TernaryNode *previous = NULL;
+        TernaryNode *latest = NULL;
+        for (int i = 0; i < nodeCount; ++i) {
+            latest = new TernaryNode(vnode->chars[i]);
+            if (latest == NULL) {
+                status = U_MEMORY_ALLOCATION_ERROR;
+                break;
+            }
+            if (head == NULL) {
+                head = latest;
+            }
+            if (previous != NULL) {
+                previous->equal = latest;
+            }
+            previous = latest;
+        }
+        if (latest != NULL) {
+            const CompactTrieNode *equal = getCompactNode(header, vnode->equal);
+            if (equal->flagscount & kParentEndsWord) {
+                latest->flags |= kEndsWord;
+            }
+            latest->equal = unpackOneNode(header, equal, status);
+        }
+        return head;
+    }
+    else {
+        // Horizontal node
+        const CompactTrieHorizontalNode *hnode = (const CompactTrieHorizontalNode *)node;
+        return unpackHorizontalArray(header, &hnode->entries[0], 0, nodeCount-1, status);
+    }
+}
+
+MutableTrieDictionary *
+CompactTrieDictionary::cloneMutable( UErrorCode &status ) const {
+    MutableTrieDictionary *result = new MutableTrieDictionary( status );
+    if (result == NULL) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
+    }
+    TernaryNode *root = unpackOneNode(fData, getCompactNode(fData, fData->root), status);
+    if (U_FAILURE(status)) {
+        delete root;    // Clean up
+        delete result;
+        return NULL;
+    }
+    result->fTrie = root;
+    return result;
+}
+
+U_NAMESPACE_END
+
+U_CAPI int32_t U_EXPORT2
+triedict_swap(const UDataSwapper *ds, const void *inData, int32_t length, void *outData,
+           UErrorCode *status) {
+
+    if (status == NULL || U_FAILURE(*status)) {
+        return 0;
+    }
+    if(ds==NULL || inData==NULL || length<-1 || (length>0 && outData==NULL)) {
+        *status=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    //
+    //  Check that the data header is for for dictionary data.
+    //    (Header contents are defined in genxxx.cpp)
+    //
+    const UDataInfo *pInfo = (const UDataInfo *)((const uint8_t *)inData+4);
+    if(!(  pInfo->dataFormat[0]==0x54 &&   /* dataFormat="TrDc" */
+           pInfo->dataFormat[1]==0x72 &&
+           pInfo->dataFormat[2]==0x44 &&
+           pInfo->dataFormat[3]==0x63 &&
+           pInfo->formatVersion[0]==1  )) {
+        udata_printError(ds, "triedict_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized\n",
+                         pInfo->dataFormat[0], pInfo->dataFormat[1],
+                         pInfo->dataFormat[2], pInfo->dataFormat[3],
+                         pInfo->formatVersion[0]);
+        *status=U_UNSUPPORTED_ERROR;
+        return 0;
+    }
+
+    //
+    // Swap the data header.  (This is the generic ICU Data Header, not the 
+    //                         CompactTrieHeader).  This swap also conveniently gets us
+    //                         the size of the ICU d.h., which lets us locate the start
+    //                         of the RBBI specific data.
+    //
+    int32_t headerSize=udata_swapDataHeader(ds, inData, length, outData, status);
+
+    //
+    // Get the CompactTrieHeader, and check that it appears to be OK.
+    //
+    const uint8_t  *inBytes =(const uint8_t *)inData+headerSize;
+    const CompactTrieHeader *header = (const CompactTrieHeader *)inBytes;
+    if (ds->readUInt32(header->magic) != COMPACT_TRIE_MAGIC_1
+            || ds->readUInt32(header->size) < sizeof(CompactTrieHeader))
+    {
+        udata_printError(ds, "triedict_swap(): CompactTrieHeader is invalid.\n");
+        *status=U_UNSUPPORTED_ERROR;
+        return 0;
+    }
+
+    //
+    // Prefight operation?  Just return the size
+    //
+    uint32_t totalSize = ds->readUInt32(header->size);
+    int32_t sizeWithUData = (int32_t)totalSize + headerSize;
+    if (length < 0) {
+        return sizeWithUData;
+    }
+
+    //
+    // Check that length passed in is consistent with length from RBBI data header.
+    //
+    if (length < sizeWithUData) {
+        udata_printError(ds, "triedict_swap(): too few bytes (%d after ICU Data header) for trie data.\n",
+                            totalSize);
+        *status=U_INDEX_OUTOFBOUNDS_ERROR;
+        return 0;
+        }
+
+    //
+    // Swap the Data.  Do the data itself first, then the CompactTrieHeader, because
+    //                 we need to reference the header to locate the data, and an
+    //                 inplace swap of the header leaves it unusable.
+    //
+    uint8_t             *outBytes = (uint8_t *)outData + headerSize;
+    CompactTrieHeader   *outputHeader = (CompactTrieHeader *)outBytes;
+
+#if 0
+    //
+    // If not swapping in place, zero out the output buffer before starting.
+    //
+    if (inBytes != outBytes) {
+        uprv_memset(outBytes, 0, totalSize);
+    }
+
+    // We need to loop through all the nodes in the offset table, and swap each one.
+    uint16_t nodeCount = ds->readUInt16(header->nodeCount);
+    // Skip node 0, which should always be 0.
+    for (int i = 1; i < nodeCount; ++i) {
+        uint32_t nodeOff = ds->readUInt32(header->offsets[i]);
+        const CompactTrieNode *inNode = (const CompactTrieNode *)(inBytes + nodeOff);
+        CompactTrieNode *outNode = (CompactTrieNode *)(outBytes + nodeOff);
+        uint16_t flagscount = ds->readUInt16(inNode->flagscount);
+        uint16_t itemCount = flagscount & kCountMask;
+        ds->writeUInt16(&outNode->flagscount, flagscount);
+        if (itemCount > 0) {
+            if (flagscount & kVerticalNode) {
+                ds->swapArray16(ds, inBytes+nodeOff+offsetof(CompactTrieVerticalNode,chars),
+                                    itemCount*sizeof(uint16_t),
+                                    outBytes+nodeOff+offsetof(CompactTrieVerticalNode,chars), status);
+                uint16_t equal = ds->readUInt16(inBytes+nodeOff+offsetof(CompactTrieVerticalNode,equal);
+                ds->writeUInt16(outBytes+nodeOff+offsetof(CompactTrieVerticalNode,equal));
+            }
+            else {
+                const CompactTrieHorizontalNode *inHNode = (const CompactTrieHorizontalNode *)inNode;
+                CompactTrieHorizontalNode *outHNode = (CompactTrieHorizontalNode *)outNode;
+                for (int j = 0; j < itemCount; ++j) {
+                    uint16_t word = ds->readUInt16(inHNode->entries[j].ch);
+                    ds->writeUInt16(&outHNode->entries[j].ch, word);
+                    word = ds->readUInt16(inHNode->entries[j].equal);
+                    ds->writeUInt16(&outHNode->entries[j].equal, word);
+                }
+            }
+        }
+    }
+#endif
+
+    // All the data in all the nodes consist of 16 bit items. Swap them all at once.
+    uint16_t nodeCount = ds->readUInt16(header->nodeCount);
+    uint32_t nodesOff = offsetof(CompactTrieHeader,offsets)+((uint32_t)nodeCount*sizeof(uint32_t));
+    ds->swapArray16(ds, inBytes+nodesOff, totalSize-nodesOff, outBytes+nodesOff, status);
+
+    // Swap the header
+    ds->writeUInt32(&outputHeader->size, totalSize);
+    uint32_t magic = ds->readUInt32(header->magic);
+    ds->writeUInt32(&outputHeader->magic, magic);
+    ds->writeUInt16(&outputHeader->nodeCount, nodeCount);
+    uint16_t root = ds->readUInt16(header->root);
+    ds->writeUInt16(&outputHeader->root, root);
+    ds->swapArray32(ds, inBytes+offsetof(CompactTrieHeader,offsets),
+            sizeof(uint32_t)*(int32_t)nodeCount,
+            outBytes+offsetof(CompactTrieHeader,offsets), status);
+
+    return sizeWithUData;
+}
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/icu/source/common/triedict.h b/icu/source/common/triedict.h
new file mode 100644
index 0000000..b879661
--- /dev/null
+++ b/icu/source/common/triedict.h
@@ -0,0 +1,346 @@
+/**
+ *******************************************************************************
+ * Copyright (C) 2006, International Business Machines Corporation and others. *
+ * All Rights Reserved.                                                        *
+ *******************************************************************************
+ */
+
+#ifndef TRIEDICT_H
+#define TRIEDICT_H
+
+#include "unicode/utypes.h"
+#include "unicode/uobject.h"
+#include "unicode/utext.h"
+
+struct UEnumeration;
+struct UDataSwapper;
+struct UDataMemory;
+
+ /**
+  * <p>UDataSwapFn function for use in swapping a compact dictionary.</p>
+  *
+  * @param ds Pointer to UDataSwapper containing global data about the
+  *           transformation and function pointers for handling primitive
+  *           types.
+  * @param inData Pointer to the input data to be transformed or examined.
+  * @param length Length of the data, counting bytes. May be -1 for preflighting.
+  *               If length>=0, then transform the data.
+  *               If length==-1, then only determine the length of the data.
+  *               The length cannot be determined from the data itself for all
+  *               types of data (e.g., not for simple arrays of integers).
+  * @param outData Pointer to the output data buffer.
+  *                If length>=0 (transformation), then the output buffer must
+  *                have a capacity of at least length.
+  *                If length==-1, then outData will not be used and can be NULL.
+  * @param pErrorCode ICU UErrorCode parameter, must not be NULL and must
+  *                   fulfill U_SUCCESS on input.
+  * @return The actual length of the data.
+  *
+  * @see UDataSwapper
+  */
+
+U_CAPI int32_t U_EXPORT2
+triedict_swap(const UDataSwapper *ds,
+            const void *inData, int32_t length, void *outData,
+            UErrorCode *pErrorCode);
+
+U_NAMESPACE_BEGIN
+
+class StringEnumeration;
+struct CompactTrieHeader;
+
+/*******************************************************************
+ * TrieWordDictionary
+ */
+
+/**
+ * <p>TrieWordDictionary is an abstract class that represents a word
+ * dictionary based on a trie. The base protocol is read-only.
+ * Subclasses may allow writing.</p>
+ */
+class U_COMMON_API TrieWordDictionary : public UMemory {
+ public:
+
+  /**
+   * <p>Default constructor.</p>
+   *
+   */
+  TrieWordDictionary();
+
+  /**
+   * <p>Virtual destructor.</p>
+   */
+  virtual ~TrieWordDictionary();
+
+ /**
+  * <p>Find dictionary words that match the text.</p>
+  *
+  * @param text A UText representing the text. The
+  * iterator is left after the longest prefix match in the dictionary.
+  * @param start The current position in text.
+  * @param maxLength The maximum number of code units to match.
+  * @param lengths An array that is filled with the lengths of words that matched.
+  * @param count Filled with the number of elements output in lengths.
+  * @param limit The size of the lengths array; this limits the number of words output.
+  * @return The number of characters in text that were matched.
+  */
+  virtual int32_t matches( UText *text,
+                              int32_t maxLength,
+                              int32_t *lengths,
+                              int &count,
+                              int limit ) const = 0;
+
+  /**
+   * <p>Return a StringEnumeration for iterating all the words in the dictionary.</p>
+   *
+   * @param status A status code recording the success of the call.
+   * @return A StringEnumeration that will iterate through the whole dictionary.
+   * The caller is responsible for closing it. The order is unspecified.
+   */
+  virtual StringEnumeration *openWords( UErrorCode &status ) const = 0;
+
+};
+
+/*******************************************************************
+ * MutableTrieDictionary
+ */
+
+/**
+ * <p>MutableTrieDictionary is a TrieWordDictionary that allows words to be
+ * added.</p>
+ */
+
+struct TernaryNode;             // Forwards declaration
+
+class U_COMMON_API MutableTrieDictionary : public TrieWordDictionary {
+ private:
+    /**
+     * The root node of the trie
+     * @internal
+     */
+
+  TernaryNode               *fTrie;
+
+    /**
+     * A UText for internal use
+     * @internal
+     */
+
+  UText    *fIter;
+
+  friend class CompactTrieDictionary;   // For fast conversion
+
+ public:
+
+ /**
+  * <p>Constructor.</p>
+  *
+  * @param median A UChar around which to balance the trie. Ideally, it should
+  * begin at least one word that is near the median of the set in the dictionary
+  * @param status A status code recording the success of the call.
+  */
+  MutableTrieDictionary( UChar median, UErrorCode &status );
+
+  /**
+   * <p>Virtual destructor.</p>
+   */
+  virtual ~MutableTrieDictionary();
+
+ /**
+  * <p>Find dictionary words that match the text.</p>
+  *
+  * @param text A UText representing the text. The
+  * iterator is left after the longest prefix match in the dictionary.
+  * @param maxLength The maximum number of code units to match.
+  * @param lengths An array that is filled with the lengths of words that matched.
+  * @param count Filled with the number of elements output in lengths.
+  * @param limit The size of the lengths array; this limits the number of words output.
+  * @return The number of characters in text that were matched.
+  */
+  virtual int32_t matches( UText *text,
+                              int32_t maxLength,
+                              int32_t *lengths,
+                              int &count,
+                              int limit ) const;
+
+  /**
+   * <p>Return a StringEnumeration for iterating all the words in the dictionary.</p>
+   *
+   * @param status A status code recording the success of the call.
+   * @return A StringEnumeration that will iterate through the whole dictionary.
+   * The caller is responsible for closing it. The order is unspecified.
+   */
+  virtual StringEnumeration *openWords( UErrorCode &status ) const;
+
+ /**
+  * <p>Add one word to the dictionary.</p>
+  *
+  * @param word A UChar buffer containing the word.
+  * @param length The length of the word.
+  * @param status The resultant status
+  */
+  virtual void addWord( const UChar *word,
+                        int32_t length,
+                        UErrorCode &status);
+
+#if 0
+ /**
+  * <p>Add all strings from a UEnumeration to the dictionary.</p>
+  *
+  * @param words A UEnumeration that will return the desired words.
+  * @param status The resultant status
+  */
+  virtual void addWords( UEnumeration *words, UErrorCode &status );
+#endif
+
+protected:
+ /**
+  * <p>Search the dictionary for matches.</p>
+  *
+  * @param text A UText representing the text. The
+  * iterator is left after the longest prefix match in the dictionary.
+  * @param maxLength The maximum number of code units to match.
+  * @param lengths An array that is filled with the lengths of words that matched.
+  * @param count Filled with the number of elements output in lengths.
+  * @param limit The size of the lengths array; this limits the number of words output.
+  * @param parent The parent of the current node
+  * @param pMatched The returned parent node matched the input
+  * @return The number of characters in text that were matched.
+  */
+  virtual int32_t search( UText *text,
+                              int32_t maxLength,
+                              int32_t *lengths,
+                              int &count,
+                              int limit,
+                              TernaryNode *&parent,
+                              UBool &pMatched ) const;
+
+private:
+ /**
+  * <p>Private constructor. The root node it not allocated.</p>
+  *
+  * @param status A status code recording the success of the call.
+  */
+  MutableTrieDictionary( UErrorCode &status );
+};
+
+/*******************************************************************
+ * CompactTrieDictionary
+ */
+
+/**
+ * <p>CompactTrieDictionary is a TrieWordDictionary that has been compacted
+ * to save space.</p>
+ */
+class U_COMMON_API CompactTrieDictionary : public TrieWordDictionary {
+ private:
+    /**
+     * The root node of the trie
+     */
+
+  const CompactTrieHeader   *fData;
+
+    /**
+     * A UBool indicating whether or not we own the fData.
+     */
+
+  UBool                     fOwnData;
+
+    UDataMemory              *fUData;
+ public:
+  /**
+   * <p>Construct a dictionary from a UDataMemory.</p>
+   *
+   * @param data A pointer to a UDataMemory, which is adopted
+   * @param status A status code giving the result of the constructor
+   */
+  CompactTrieDictionary(UDataMemory *dataObj, UErrorCode &status);
+
+  /**
+   * <p>Construct a dictionary from raw saved data.</p>
+   *
+   * @param data A pointer to the raw data, which is still owned by the caller
+   * @param status A status code giving the result of the constructor
+   */
+  CompactTrieDictionary(const void *dataObj, UErrorCode &status);
+
+  /**
+   * <p>Construct a dictionary from a MutableTrieDictionary.</p>
+   *
+   * @param dict The dictionary to use as input.
+   * @param status A status code recording the success of the call.
+   */
+  CompactTrieDictionary( const MutableTrieDictionary &dict, UErrorCode &status );
+
+  /**
+   * <p>Virtual destructor.</p>
+   */
+  virtual ~CompactTrieDictionary();
+
+ /**
+  * <p>Find dictionary words that match the text.</p>
+  *
+  * @param text A UText representing the text. The
+  * iterator is left after the longest prefix match in the dictionary.
+  * @param maxLength The maximum number of code units to match.
+  * @param lengths An array that is filled with the lengths of words that matched.
+  * @param count Filled with the number of elements output in lengths.
+  * @param limit The size of the lengths array; this limits the number of words output.
+  * @return The number of characters in text that were matched.
+  */
+  virtual int32_t matches( UText *text,
+                              int32_t rangeEnd,
+                              int32_t *lengths,
+                              int &count,
+                              int limit ) const;
+
+  /**
+   * <p>Return a StringEnumeration for iterating all the words in the dictionary.</p>
+   *
+   * @param status A status code recording the success of the call.
+   * @return A StringEnumeration that will iterate through the whole dictionary.
+   * The caller is responsible for closing it. The order is unspecified.
+   */
+  virtual StringEnumeration *openWords( UErrorCode &status ) const;
+
+ /**
+  * <p>Return the size of the compact data.</p>
+  *
+  * @return The size of the dictionary's compact data.
+  */
+  virtual uint32_t dataSize() const;
+  
+ /**
+  * <p>Return a void * pointer to the compact data, platform-endian.</p>
+  *
+  * @return The data for the compact dictionary, suitable for passing to the
+  * constructor.
+  */
+  virtual const void *data() const;
+  
+ /**
+  * <p>Return a MutableTrieDictionary clone of this dictionary.</p>
+  *
+  * @param status A status code recording the success of the call.
+  * @return A MutableTrieDictionary with the same data as this dictionary
+  */
+  virtual MutableTrieDictionary *cloneMutable( UErrorCode &status ) const;
+  
+ private:
+ 
+  /**
+   * <p>Convert a MutableTrieDictionary into a compact data blob.</p>
+   *
+   * @param dict The dictionary to convert.
+   * @param status A status code recording the success of the call.
+   * @return A single data blob starting with a CompactTrieHeader.
+   */
+  static CompactTrieHeader *compactMutableTrieDictionary( const MutableTrieDictionary &dict,
+                                                        UErrorCode &status );
+
+};
+
+U_NAMESPACE_END
+
+    /* TRIEDICT_H */
+#endif
diff --git a/icu/source/common/uarrsort.c b/icu/source/common/uarrsort.c
new file mode 100644
index 0000000..8bc967c
--- /dev/null
+++ b/icu/source/common/uarrsort.c
@@ -0,0 +1,236 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2003, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  uarrsort.c
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2003aug04
+*   created by: Markus W. Scherer
+*
+*   Internal function for sorting arrays.
+*/
+
+#include "unicode/utypes.h"
+#include "cmemory.h"
+#include "uarrsort.h"
+
+enum {
+    MIN_QSORT=9, /* from Knuth */
+    STACK_ITEM_SIZE=200
+};
+
+/* UComparator convenience implementations ---------------------------------- */
+
+U_CAPI int32_t U_EXPORT2
+uprv_uint16Comparator(const void *context, const void *left, const void *right) {
+    return (int32_t)*(const uint16_t *)left - (int32_t)*(const uint16_t *)right;
+}
+
+U_CAPI int32_t U_EXPORT2
+uprv_int32Comparator(const void *context, const void *left, const void *right) {
+    return *(const int32_t *)left - *(const int32_t *)right;
+}
+
+U_CAPI int32_t U_EXPORT2
+uprv_uint32Comparator(const void *context, const void *left, const void *right) {
+    uint32_t l=*(const uint32_t *)left, r=*(const uint32_t *)right;
+
+    /* compare directly because (l-r) would overflow the int32_t result */
+    if(l<r) {
+        return -1;
+    } else if(l==r) {
+        return 0;
+    } else /* l>r */ {
+        return 1;
+    }
+}
+
+/* Straight insertion sort from Knuth vol. III, pg. 81 ---------------------- */
+
+static void
+doInsertionSort(char *array, int32_t start, int32_t limit, int32_t itemSize,
+                UComparator *cmp, const void *context, void *pv) {
+    int32_t i, j;
+
+    for(j=start+1; j<limit; ++j) {
+        /* v=array[j] */
+        uprv_memcpy(pv, array+j*itemSize, itemSize);
+
+        for(i=j; i>start; --i) {
+            if(/* v>=array[i-1] */ cmp(context, pv, array+(i-1)*itemSize)>=0) {
+                break;
+            }
+
+            /* array[i]=array[i-1]; */
+            uprv_memcpy(array+i*itemSize, array+(i-1)*itemSize, itemSize);
+        }
+
+        if(i!=j) {
+            /* array[i]=v; */
+            uprv_memcpy(array+i*itemSize, pv, itemSize);
+        }
+    }
+}
+
+static void
+insertionSort(char *array, int32_t length, int32_t itemSize,
+              UComparator *cmp, const void *context, UErrorCode *pErrorCode) {
+    UAlignedMemory v[STACK_ITEM_SIZE/sizeof(UAlignedMemory)+1];
+    void *pv;
+
+    /* allocate an intermediate item variable (v) */
+    if(itemSize<=STACK_ITEM_SIZE) {
+        pv=v;
+    } else {
+        pv=uprv_malloc(itemSize);
+        if(pv==NULL) {
+            *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+    }
+
+    doInsertionSort(array, 0, length, itemSize, cmp, context, pv);
+
+    if(pv!=v) {
+        uprv_free(pv);
+    }
+}
+
+/* QuickSort ---------------------------------------------------------------- */
+
+/*
+ * This implementation is semi-recursive:
+ * It recurses for the smaller sub-array to shorten the recursion depth,
+ * and loops for the larger sub-array.
+ *
+ * Loosely after QuickSort algorithms in
+ * Niklaus Wirth
+ * Algorithmen und Datenstrukturen mit Modula-2
+ * B.G. Teubner Stuttgart
+ * 4. Auflage 1986
+ * ISBN 3-519-02260-5
+ */
+static void
+subQuickSort(char *array, int32_t start, int32_t limit, int32_t itemSize,
+             UComparator *cmp, const void *context,
+             void *px, void *pw) {
+    int32_t left, right;
+
+    /* start and left are inclusive, limit and right are exclusive */
+    do {
+        if((start+MIN_QSORT)>=limit) {
+            doInsertionSort(array, start, limit, itemSize, cmp, context, px);
+            break;
+        }
+
+        left=start;
+        right=limit;
+
+        /* x=array[middle] */
+        uprv_memcpy(px, array+((start+limit)/2)*itemSize, itemSize);
+
+        do {
+            while(/* array[left]<x */
+                  cmp(context, array+left*itemSize, px)<0
+            ) {
+                ++left;
+            }
+            while(/* x<array[right-1] */
+                  cmp(context, px, array+(right-1)*itemSize)<0
+            ) {
+                --right;
+            }
+
+            /* swap array[left] and array[right-1] via w; ++left; --right */
+            if(left<right) {
+                --right;
+
+                if(left<right) {
+                    uprv_memcpy(pw, array+left*itemSize, itemSize);
+                    uprv_memcpy(array+left*itemSize, array+right*itemSize, itemSize);
+                    uprv_memcpy(array+right*itemSize, pw, itemSize);
+                }
+
+                ++left;
+            }
+        } while(left<right);
+
+        /* sort sub-arrays */
+        if((right-start)<(limit-left)) {
+            /* sort [start..right[ */
+            if(start<(right-1)) {
+                subQuickSort(array, start, right, itemSize, cmp, context, px, pw);
+            }
+
+            /* sort [left..limit[ */
+            start=left;
+        } else {
+            /* sort [left..limit[ */
+            if(left<(limit-1)) {
+                subQuickSort(array, left, limit, itemSize, cmp, context, px, pw);
+            }
+
+            /* sort [start..right[ */
+            limit=right;
+        }
+    } while(start<(limit-1));
+}
+
+static void
+quickSort(char *array, int32_t length, int32_t itemSize,
+            UComparator *cmp, const void *context, UErrorCode *pErrorCode) {
+    UAlignedMemory xw[(2*STACK_ITEM_SIZE)/sizeof(UAlignedMemory)+1];
+    void *p;
+
+    /* allocate two intermediate item variables (x and w) */
+    if(itemSize<=STACK_ITEM_SIZE) {
+        p=xw;
+    } else {
+        p=uprv_malloc(2*itemSize);
+        if(p==NULL) {
+            *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+    }
+
+    subQuickSort(array, 0, length, itemSize,
+                 cmp, context, p, (char *)p+itemSize);
+
+    if(p!=xw) {
+        uprv_free(p);
+    }
+}
+
+/* uprv_sortArray() API ----------------------------------------------------- */
+
+/*
+ * Check arguments, select an appropriate implementation,
+ * cast the array to char * so that array+i*itemSize works.
+ */
+U_CAPI void U_EXPORT2
+uprv_sortArray(void *array, int32_t length, int32_t itemSize,
+               UComparator *cmp, const void *context,
+               UBool sortStable, UErrorCode *pErrorCode) {
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return;
+    }
+    if((length>0 && array==NULL) || length<0 || itemSize<=0 || cmp==NULL) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    if(length<=1) {
+        return;
+    } else if(length<MIN_QSORT || sortStable) {
+        insertionSort((char *)array, length, itemSize, cmp, context, pErrorCode);
+        /* could add heapSort or similar for stable sorting of longer arrays */
+    } else {
+        quickSort((char *)array, length, itemSize, cmp, context, pErrorCode);
+    }
+}
diff --git a/icu/source/common/uarrsort.h b/icu/source/common/uarrsort.h
new file mode 100644
index 0000000..b9a580c
--- /dev/null
+++ b/icu/source/common/uarrsort.h
@@ -0,0 +1,84 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2003, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  uarrsort.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2003aug04
+*   created by: Markus W. Scherer
+*
+*   Internal function for sorting arrays.
+*/
+
+#ifndef __UARRSORT_H__
+#define __UARRSORT_H__
+
+#include "unicode/utypes.h"
+
+U_CDECL_BEGIN
+/**
+ * Function type for comparing two items as part of sorting an array or similar.
+ * Callback function for uprv_sortArray().
+ *
+ * @param context Application-specific pointer, passed through by uprv_sortArray().
+ * @param left    Pointer to the "left" item.
+ * @param right   Pointer to the "right" item.
+ * @return 32-bit signed integer comparison result:
+ *                <0 if left<right
+ *               ==0 if left==right
+ *                >0 if left>right
+ *
+ * @internal
+ */
+typedef int32_t U_CALLCONV
+UComparator(const void *context, const void *left, const void *right);
+U_CDECL_END
+
+/**
+ * Array sorting function.
+ * Uses a UComparator for comparing array items to each other, and simple
+ * memory copying to move items.
+ *
+ * @param array      The array to be sorted.
+ * @param length     The number of items in the array.
+ * @param itemSize   The size in bytes of each array item.
+ * @param cmp        UComparator function used to compare two items each.
+ * @param context    Application-specific pointer, passed through to the UComparator.
+ * @param sortStable If true, a stable sorting algorithm must be used.
+ * @param pErrorCode ICU in/out UErrorCode parameter.
+ *
+ * @internal
+ */
+U_CAPI void U_EXPORT2
+uprv_sortArray(void *array, int32_t length, int32_t itemSize,
+               UComparator *cmp, const void *context,
+               UBool sortStable, UErrorCode *pErrorCode);
+
+/**
+ * Convenience UComparator implementation for uint16_t arrays.
+ * @internal
+ */
+U_CAPI int32_t U_EXPORT2
+uprv_uint16Comparator(const void *context, const void *left, const void *right);
+
+/**
+ * Convenience UComparator implementation for int32_t arrays.
+ * @internal
+ */
+U_CAPI int32_t U_EXPORT2
+uprv_int32Comparator(const void *context, const void *left, const void *right);
+
+/**
+ * Convenience UComparator implementation for uint32_t arrays.
+ * @internal
+ */
+U_CAPI int32_t U_EXPORT2
+uprv_uint32Comparator(const void *context, const void *left, const void *right);
+
+#endif
diff --git a/icu/source/common/uassert.h b/icu/source/common/uassert.h
new file mode 100644
index 0000000..9b1a141
--- /dev/null
+++ b/icu/source/common/uassert.h
@@ -0,0 +1,32 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 2002-2003, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+* File uassert.h
+*
+*  Contains U_ASSERT macro
+*
+*    By default, U_ASSERT just wraps the C library assert macro.
+*    By changing the definition here, the assert behavior for ICU can be changed
+*    without affecting other non-ICU uses of the C library assert().
+*
+******************************************************************************
+*/
+
+#ifndef U_ASSERT_H
+#define U_ASSERT_H
+/* utypes.h is included to get the proper define for uint8_t */
+#include "unicode/utypes.h"
+#if U_RELEASE
+#define U_ASSERT(exp)
+#else
+#include <assert.h>
+#define U_ASSERT(exp) assert(exp)
+#endif
+#endif
+
+
diff --git a/icu/source/common/ubidi.c b/icu/source/common/ubidi.c
new file mode 100644
index 0000000..fb5799b
--- /dev/null
+++ b/icu/source/common/ubidi.c
@@ -0,0 +1,2216 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1999-2009, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*   file name:  ubidi.c
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 1999jul27
+*   created by: Markus W. Scherer, updated by Matitiahu Allouche
+*/
+
+#include "cmemory.h"
+#include "unicode/utypes.h"
+#include "unicode/ustring.h"
+#include "unicode/uchar.h"
+#include "unicode/ubidi.h"
+#include "ubidi_props.h"
+#include "ubidiimp.h"
+#include "uassert.h"
+
+/*
+ * General implementation notes:
+ *
+ * Throughout the implementation, there are comments like (W2) that refer to
+ * rules of the BiDi algorithm in its version 5, in this example to the second
+ * rule of the resolution of weak types.
+ *
+ * For handling surrogate pairs, where two UChar's form one "abstract" (or UTF-32)
+ * character according to UTF-16, the second UChar gets the directional property of
+ * the entire character assigned, while the first one gets a BN, a boundary
+ * neutral, type, which is ignored by most of the algorithm according to
+ * rule (X9) and the implementation suggestions of the BiDi algorithm.
+ *
+ * Later, adjustWSLevels() will set the level for each BN to that of the
+ * following character (UChar), which results in surrogate pairs getting the
+ * same level on each of their surrogates.
+ *
+ * In a UTF-8 implementation, the same thing could be done: the last byte of
+ * a multi-byte sequence would get the "real" property, while all previous
+ * bytes of that sequence would get BN.
+ *
+ * It is not possible to assign all those parts of a character the same real
+ * property because this would fail in the resolution of weak types with rules
+ * that look at immediately surrounding types.
+ *
+ * As a related topic, this implementation does not remove Boundary Neutral
+ * types from the input, but ignores them wherever this is relevant.
+ * For example, the loop for the resolution of the weak types reads
+ * types until it finds a non-BN.
+ * Also, explicit embedding codes are neither changed into BN nor removed.
+ * They are only treated the same way real BNs are.
+ * As stated before, adjustWSLevels() takes care of them at the end.
+ * For the purpose of conformance, the levels of all these codes
+ * do not matter.
+ *
+ * Note that this implementation never modifies the dirProps
+ * after the initial setup.
+ *
+ *
+ * In this implementation, the resolution of weak types (Wn),
+ * neutrals (Nn), and the assignment of the resolved level (In)
+ * are all done in one single loop, in resolveImplicitLevels().
+ * Changes of dirProp values are done on the fly, without writing
+ * them back to the dirProps array.
+ *
+ *
+ * This implementation contains code that allows to bypass steps of the
+ * algorithm that are not needed on the specific paragraph
+ * in order to speed up the most common cases considerably,
+ * like text that is entirely LTR, or RTL text without numbers.
+ *
+ * Most of this is done by setting a bit for each directional property
+ * in a flags variable and later checking for whether there are
+ * any LTR characters or any RTL characters, or both, whether
+ * there are any explicit embedding codes, etc.
+ *
+ * If the (Xn) steps are performed, then the flags are re-evaluated,
+ * because they will then not contain the embedding codes any more
+ * and will be adjusted for override codes, so that subsequently
+ * more bypassing may be possible than what the initial flags suggested.
+ *
+ * If the text is not mixed-directional, then the
+ * algorithm steps for the weak type resolution are not performed,
+ * and all levels are set to the paragraph level.
+ *
+ * If there are no explicit embedding codes, then the (Xn) steps
+ * are not performed.
+ *
+ * If embedding levels are supplied as a parameter, then all
+ * explicit embedding codes are ignored, and the (Xn) steps
+ * are not performed.
+ *
+ * White Space types could get the level of the run they belong to,
+ * and are checked with a test of (flags&MASK_EMBEDDING) to
+ * consider if the paragraph direction should be considered in
+ * the flags variable.
+ *
+ * If there are no White Space types in the paragraph, then
+ * (L1) is not necessary in adjustWSLevels().
+ */
+
+/* to avoid some conditional statements, use tiny constant arrays */
+static const Flags flagLR[2]={ DIRPROP_FLAG(L), DIRPROP_FLAG(R) };
+static const Flags flagE[2]={ DIRPROP_FLAG(LRE), DIRPROP_FLAG(RLE) };
+static const Flags flagO[2]={ DIRPROP_FLAG(LRO), DIRPROP_FLAG(RLO) };
+
+#define DIRPROP_FLAG_LR(level) flagLR[(level)&1]
+#define DIRPROP_FLAG_E(level) flagE[(level)&1]
+#define DIRPROP_FLAG_O(level) flagO[(level)&1]
+
+/* UBiDi object management -------------------------------------------------- */
+
+U_CAPI UBiDi * U_EXPORT2
+ubidi_open(void)
+{
+    UErrorCode errorCode=U_ZERO_ERROR;
+    return ubidi_openSized(0, 0, &errorCode);
+}
+
+U_CAPI UBiDi * U_EXPORT2
+ubidi_openSized(int32_t maxLength, int32_t maxRunCount, UErrorCode *pErrorCode) {
+    UBiDi *pBiDi;
+
+    /* check the argument values */
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return NULL;
+    } else if(maxLength<0 || maxRunCount<0) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return NULL;    /* invalid arguments */
+    }
+
+    /* allocate memory for the object */
+    pBiDi=(UBiDi *)uprv_malloc(sizeof(UBiDi));
+    if(pBiDi==NULL) {
+        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
+    }
+
+    /* reset the object, all pointers NULL, all flags FALSE, all sizes 0 */
+    uprv_memset(pBiDi, 0, sizeof(UBiDi));
+
+    /* get BiDi properties */
+    pBiDi->bdp=ubidi_getSingleton(pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        uprv_free(pBiDi);
+        return NULL;
+    }
+
+    /* allocate memory for arrays as requested */
+    if(maxLength>0) {
+        if( !getInitialDirPropsMemory(pBiDi, maxLength) ||
+            !getInitialLevelsMemory(pBiDi, maxLength)
+        ) {
+            *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+        }
+    } else {
+        pBiDi->mayAllocateText=TRUE;
+    }
+
+    if(maxRunCount>0) {
+        if(maxRunCount==1) {
+            /* use simpleRuns[] */
+            pBiDi->runsSize=sizeof(Run);
+        } else if(!getInitialRunsMemory(pBiDi, maxRunCount)) {
+            *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+        }
+    } else {
+        pBiDi->mayAllocateRuns=TRUE;
+    }
+
+    if(U_SUCCESS(*pErrorCode)) {
+        return pBiDi;
+    } else {
+        ubidi_close(pBiDi);
+        return NULL;
+    }
+}
+
+/*
+ * We are allowed to allocate memory if memory==NULL or
+ * mayAllocate==TRUE for each array that we need.
+ * We also try to grow memory as needed if we
+ * allocate it.
+ *
+ * Assume sizeNeeded>0.
+ * If *pMemory!=NULL, then assume *pSize>0.
+ *
+ * ### this realloc() may unnecessarily copy the old data,
+ * which we know we don't need any more;
+ * is this the best way to do this??
+ */
+U_CFUNC UBool
+ubidi_getMemory(BidiMemoryForAllocation *bidiMem, int32_t *pSize, UBool mayAllocate, int32_t sizeNeeded) {
+    void **pMemory = (void **)bidiMem;
+    /* check for existing memory */
+    if(*pMemory==NULL) {
+        /* we need to allocate memory */
+        if(mayAllocate && (*pMemory=uprv_malloc(sizeNeeded))!=NULL) {
+            *pSize=sizeNeeded;
+            return TRUE;
+        } else {
+            return FALSE;
+        }
+    } else {
+        if(sizeNeeded<=*pSize) {
+            /* there is already enough memory */
+            return TRUE;
+        }
+        else if(!mayAllocate) {
+            /* not enough memory, and we must not allocate */
+            return FALSE;
+        } else {
+            /* we try to grow */
+            void *memory;
+            /* in most cases, we do not need the copy-old-data part of
+             * realloc, but it is needed when adding runs using getRunsMemory()
+             * in setParaRunsOnly()
+             */
+            if((memory=uprv_realloc(*pMemory, sizeNeeded))!=NULL) {
+                *pMemory=memory;
+                *pSize=sizeNeeded;
+                return TRUE;
+            } else {
+                /* we failed to grow */
+                return FALSE;
+            }
+        }
+    }
+}
+
+U_CAPI void U_EXPORT2
+ubidi_close(UBiDi *pBiDi) {
+    if(pBiDi!=NULL) {
+        pBiDi->pParaBiDi=NULL;          /* in case one tries to reuse this block */
+        if(pBiDi->dirPropsMemory!=NULL) {
+            uprv_free(pBiDi->dirPropsMemory);
+        }
+        if(pBiDi->levelsMemory!=NULL) {
+            uprv_free(pBiDi->levelsMemory);
+        }
+        if(pBiDi->runsMemory!=NULL) {
+            uprv_free(pBiDi->runsMemory);
+        }
+        if(pBiDi->parasMemory!=NULL) {
+            uprv_free(pBiDi->parasMemory);
+        }
+        if(pBiDi->insertPoints.points!=NULL) {
+            uprv_free(pBiDi->insertPoints.points);
+        }
+
+        uprv_free(pBiDi);
+    }
+}
+
+/* set to approximate "inverse BiDi" ---------------------------------------- */
+
+U_CAPI void U_EXPORT2
+ubidi_setInverse(UBiDi *pBiDi, UBool isInverse) {
+    if(pBiDi!=NULL) {
+        pBiDi->isInverse=isInverse;
+        pBiDi->reorderingMode = isInverse ? UBIDI_REORDER_INVERSE_NUMBERS_AS_L
+                                          : UBIDI_REORDER_DEFAULT;
+    }
+}
+
+U_CAPI UBool U_EXPORT2
+ubidi_isInverse(UBiDi *pBiDi) {
+    if(pBiDi!=NULL) {
+        return pBiDi->isInverse;
+    } else {
+        return FALSE;
+    }
+}
+
+/* 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_R
+ * 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.
+ */
+U_CAPI void U_EXPORT2
+ubidi_setReorderingMode(UBiDi *pBiDi, UBiDiReorderingMode reorderingMode) {
+    if ((pBiDi!=NULL) && (reorderingMode >= UBIDI_REORDER_DEFAULT)
+                        && (reorderingMode < UBIDI_REORDER_COUNT)) {
+        pBiDi->reorderingMode = reorderingMode;
+        pBiDi->isInverse = (UBool)(reorderingMode == UBIDI_REORDER_INVERSE_NUMBERS_AS_L);
+    }
+}
+
+U_CAPI UBiDiReorderingMode U_EXPORT2
+ubidi_getReorderingMode(UBiDi *pBiDi) {
+    if (pBiDi!=NULL) {
+        return pBiDi->reorderingMode;
+    } else {
+        return UBIDI_REORDER_DEFAULT;
+    }
+}
+
+U_CAPI void U_EXPORT2
+ubidi_setReorderingOptions(UBiDi *pBiDi, uint32_t reorderingOptions) {
+    if (reorderingOptions & UBIDI_OPTION_REMOVE_CONTROLS) {
+        reorderingOptions&=~UBIDI_OPTION_INSERT_MARKS;
+    }
+    if (pBiDi!=NULL) {
+        pBiDi->reorderingOptions=reorderingOptions;
+    }
+}
+
+U_CAPI uint32_t U_EXPORT2
+ubidi_getReorderingOptions(UBiDi *pBiDi) {
+    if (pBiDi!=NULL) {
+        return pBiDi->reorderingOptions;
+    } else {
+        return 0;
+    }
+}
+
+/* perform (P2)..(P3) ------------------------------------------------------- */
+
+/*
+ * Get the directional properties for the text,
+ * calculate the flags bit-set, and
+ * determine the paragraph level if necessary.
+ */
+static void
+getDirProps(UBiDi *pBiDi) {
+    const UChar *text=pBiDi->text;
+    DirProp *dirProps=pBiDi->dirPropsMemory;    /* pBiDi->dirProps is const */
+
+    int32_t i=0, i1, length=pBiDi->originalLength;
+    Flags flags=0;      /* collect all directionalities in the text */
+    UChar32 uchar;
+    DirProp dirProp=0, paraDirDefault=0;/* initialize to avoid compiler warnings */
+    UBool isDefaultLevel=IS_DEFAULT_LEVEL(pBiDi->paraLevel);
+    /* for inverse BiDi, the default para level is set to RTL if there is a
+       strong R or AL character at either end of the text                           */
+    UBool isDefaultLevelInverse=isDefaultLevel && (UBool)
+            (pBiDi->reorderingMode==UBIDI_REORDER_INVERSE_LIKE_DIRECT ||
+             pBiDi->reorderingMode==UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL);
+    int32_t lastArabicPos=-1;
+    int32_t controlCount=0;
+    UBool removeBiDiControls = (UBool)(pBiDi->reorderingOptions &
+                                       UBIDI_OPTION_REMOVE_CONTROLS);
+
+    typedef enum {
+         NOT_CONTEXTUAL,                /* 0: not contextual paraLevel */
+         LOOKING_FOR_STRONG,            /* 1: looking for first strong char */
+         FOUND_STRONG_CHAR              /* 2: found first strong char       */
+    } State;
+    State state;
+    int32_t paraStart=0;                /* index of first char in paragraph */
+    DirProp paraDir;                    /* == CONTEXT_RTL within paragraphs
+                                           starting with strong R char      */
+    DirProp lastStrongDir=0;            /* for default level & inverse BiDi */
+    int32_t lastStrongLTR=0;            /* for STREAMING option             */
+
+    if(pBiDi->reorderingOptions & UBIDI_OPTION_STREAMING) {
+        pBiDi->length=0;
+        lastStrongLTR=0;
+    }
+    if(isDefaultLevel) {
+        paraDirDefault=pBiDi->paraLevel&1 ? CONTEXT_RTL : 0;
+        paraDir=paraDirDefault;
+        lastStrongDir=paraDirDefault;
+        state=LOOKING_FOR_STRONG;
+    } else {
+        state=NOT_CONTEXTUAL;
+        paraDir=0;
+    }
+    /* count paragraphs and determine the paragraph level (P2..P3) */
+    /*
+     * see comment in ubidi.h:
+     * the DEFAULT_XXX values are designed so that
+     * their bit 0 alone yields the intended default
+     */
+    for( /* i=0 above */ ; i<length; ) {
+        /* i is incremented by U16_NEXT */
+        U16_NEXT(text, i, length, uchar);
+        flags|=DIRPROP_FLAG(dirProp=(DirProp)ubidi_getCustomizedClass(pBiDi, uchar));
+        dirProps[i-1]=dirProp|paraDir;
+        if(uchar>0xffff) {  /* set the lead surrogate's property to BN */
+            flags|=DIRPROP_FLAG(BN);
+            dirProps[i-2]=(DirProp)(BN|paraDir);
+        }
+        if(state==LOOKING_FOR_STRONG) {
+            if(dirProp==L) {
+                state=FOUND_STRONG_CHAR;
+                if(paraDir) {
+                    paraDir=0;
+                    for(i1=paraStart; i1<i; i1++) {
+                        dirProps[i1]&=~CONTEXT_RTL;
+                    }
+                }
+                continue;
+            }
+            if(dirProp==R || dirProp==AL) {
+                state=FOUND_STRONG_CHAR;
+                if(paraDir==0) {
+                    paraDir=CONTEXT_RTL;
+                    for(i1=paraStart; i1<i; i1++) {
+                        dirProps[i1]|=CONTEXT_RTL;
+                    }
+                }
+                continue;
+            }
+        }
+        if(dirProp==L) {
+            lastStrongDir=0;
+            lastStrongLTR=i;            /* i is index to next character */
+        }
+        else if(dirProp==R) {
+            lastStrongDir=CONTEXT_RTL;
+        }
+        else if(dirProp==AL) {
+            lastStrongDir=CONTEXT_RTL;
+            lastArabicPos=i-1;
+        }
+        else if(dirProp==B) {
+            if(pBiDi->reorderingOptions & UBIDI_OPTION_STREAMING) {
+                pBiDi->length=i;        /* i is index to next character */
+            }
+            if(isDefaultLevelInverse && (lastStrongDir==CONTEXT_RTL) &&(paraDir!=lastStrongDir)) {
+                for( ; paraStart<i; paraStart++) {
+                    dirProps[paraStart]|=CONTEXT_RTL;
+                }
+            }
+            if(i<length) {              /* B not last char in text */
+                if(!((uchar==CR) && (text[i]==LF))) {
+                    pBiDi->paraCount++;
+                }
+                if(isDefaultLevel) {
+                    state=LOOKING_FOR_STRONG;
+                    paraStart=i;        /* i is index to next character */
+                    paraDir=paraDirDefault;
+                    lastStrongDir=paraDirDefault;
+                }
+            }
+        }
+        if(removeBiDiControls && IS_BIDI_CONTROL_CHAR(uchar)) {
+            controlCount++;
+        }
+    }
+    if(isDefaultLevelInverse && (lastStrongDir==CONTEXT_RTL) &&(paraDir!=lastStrongDir)) {
+        for(i1=paraStart; i1<length; i1++) {
+            dirProps[i1]|=CONTEXT_RTL;
+        }
+    }
+    if(isDefaultLevel) {
+        pBiDi->paraLevel=GET_PARALEVEL(pBiDi, 0);
+    }
+    if(pBiDi->reorderingOptions & UBIDI_OPTION_STREAMING) {
+        if((lastStrongLTR>pBiDi->length) &&
+           (GET_PARALEVEL(pBiDi, lastStrongLTR)==0)) {
+            pBiDi->length = lastStrongLTR;
+        }
+        if(pBiDi->length<pBiDi->originalLength) {
+            pBiDi->paraCount--;
+        }
+    }
+    /* The following line does nothing new for contextual paraLevel, but is
+       needed for absolute paraLevel.                               */
+    flags|=DIRPROP_FLAG_LR(pBiDi->paraLevel);
+
+    if(pBiDi->orderParagraphsLTR && (flags&DIRPROP_FLAG(B))) {
+        flags|=DIRPROP_FLAG(L);
+    }
+
+    pBiDi->controlCount = controlCount;
+    pBiDi->flags=flags;
+    pBiDi->lastArabicPos=lastArabicPos;
+}
+
+/* perform (X1)..(X9) ------------------------------------------------------- */
+
+/* determine if the text is mixed-directional or single-directional */
+static UBiDiDirection
+directionFromFlags(UBiDi *pBiDi) {
+    Flags flags=pBiDi->flags;
+    /* if the text contains AN and neutrals, then some neutrals may become RTL */
+    if(!(flags&MASK_RTL || ((flags&DIRPROP_FLAG(AN)) && (flags&MASK_POSSIBLE_N)))) {
+        return UBIDI_LTR;
+    } else if(!(flags&MASK_LTR)) {
+        return UBIDI_RTL;
+    } else {
+        return UBIDI_MIXED;
+    }
+}
+
+/*
+ * Resolve the explicit levels as specified by explicit embedding codes.
+ * Recalculate the flags to have them reflect the real properties
+ * after taking the explicit embeddings into account.
+ *
+ * The BiDi algorithm is designed to result in the same behavior whether embedding
+ * levels are externally specified (from "styled text", supposedly the preferred
+ * method) or set by explicit embedding codes (LRx, RLx, PDF) in the plain text.
+ * That is why (X9) instructs to remove all explicit codes (and BN).
+ * However, in a real implementation, this removal of these codes and their index
+ * positions in the plain text is undesirable since it would result in
+ * reallocated, reindexed text.
+ * Instead, this implementation leaves the codes in there and just ignores them
+ * in the subsequent processing.
+ * In order to get the same reordering behavior, positions with a BN or an
+ * explicit embedding code just get the same level assigned as the last "real"
+ * character.
+ *
+ * Some implementations, not this one, then overwrite some of these
+ * directionality properties at "real" same-level-run boundaries by
+ * L or R codes so that the resolution of weak types can be performed on the
+ * entire paragraph at once instead of having to parse it once more and
+ * perform that resolution on same-level-runs.
+ * This limits the scope of the implicit rules in effectively
+ * the same way as the run limits.
+ *
+ * Instead, this implementation does not modify these codes.
+ * On one hand, the paragraph has to be scanned for same-level-runs, but
+ * on the other hand, this saves another loop to reset these codes,
+ * or saves making and modifying a copy of dirProps[].
+ *
+ *
+ * Note that (Pn) and (Xn) changed significantly from version 4 of the BiDi algorithm.
+ *
+ *
+ * Handling the stack of explicit levels (Xn):
+ *
+ * With the BiDi stack of explicit levels,
+ * as pushed with each LRE, RLE, LRO, and RLO and popped with each PDF,
+ * the explicit level must never exceed UBIDI_MAX_EXPLICIT_LEVEL==61.
+ *
+ * In order to have a correct push-pop semantics even in the case of overflows,
+ * there are two overflow counters:
+ * - countOver60 is incremented with each LRx at level 60
+ * - from level 60, one RLx increases the level to 61
+ * - countOver61 is incremented with each LRx and RLx at level 61
+ *
+ * Popping levels with PDF must work in the opposite order so that level 61
+ * is correct at the correct point. Underflows (too many PDFs) must be checked.
+ *
+ * This implementation assumes that UBIDI_MAX_EXPLICIT_LEVEL is odd.
+ */
+static UBiDiDirection
+resolveExplicitLevels(UBiDi *pBiDi) {
+    const DirProp *dirProps=pBiDi->dirProps;
+    UBiDiLevel *levels=pBiDi->levels;
+    const UChar *text=pBiDi->text;
+
+    int32_t i=0, length=pBiDi->length;
+    Flags flags=pBiDi->flags;       /* collect all directionalities in the text */
+    DirProp dirProp;
+    UBiDiLevel level=GET_PARALEVEL(pBiDi, 0);
+
+    UBiDiDirection direction;
+    int32_t paraIndex=0;
+
+    /* determine if the text is mixed-directional or single-directional */
+    direction=directionFromFlags(pBiDi);
+
+    /* we may not need to resolve any explicit levels, but for multiple
+       paragraphs we want to loop on all chars to set the para boundaries */
+    if((direction!=UBIDI_MIXED) && (pBiDi->paraCount==1)) {
+        /* not mixed directionality: levels don't matter - trailingWSStart will be 0 */
+    } else if((pBiDi->paraCount==1) &&
+              (!(flags&MASK_EXPLICIT) ||
+               (pBiDi->reorderingMode > UBIDI_REORDER_LAST_LOGICAL_TO_VISUAL))) {
+        /* mixed, but all characters are at the same embedding level */
+        /* or we are in "inverse BiDi" */
+        /* and we don't have contextual multiple paragraphs with some B char */
+        /* set all levels to the paragraph level */
+        for(i=0; i<length; ++i) {
+            levels[i]=level;
+        }
+    } else {
+        /* continue to perform (Xn) */
+
+        /* (X1) level is set for all codes, embeddingLevel keeps track of the push/pop operations */
+        /* both variables may carry the UBIDI_LEVEL_OVERRIDE flag to indicate the override status */
+        UBiDiLevel embeddingLevel=level, newLevel, stackTop=0;
+
+        UBiDiLevel stack[UBIDI_MAX_EXPLICIT_LEVEL];        /* we never push anything >=UBIDI_MAX_EXPLICIT_LEVEL */
+        uint32_t countOver60=0, countOver61=0;  /* count overflows of explicit levels */
+
+        /* recalculate the flags */
+        flags=0;
+
+        for(i=0; i<length; ++i) {
+            dirProp=NO_CONTEXT_RTL(dirProps[i]);
+            switch(dirProp) {
+            case LRE:
+            case LRO:
+                /* (X3, X5) */
+                newLevel=(UBiDiLevel)((embeddingLevel+2)&~(UBIDI_LEVEL_OVERRIDE|1)); /* least greater even level */
+                if(newLevel<=UBIDI_MAX_EXPLICIT_LEVEL) {
+                    stack[stackTop]=embeddingLevel;
+                    ++stackTop;
+                    embeddingLevel=newLevel;
+                    if(dirProp==LRO) {
+                        embeddingLevel|=UBIDI_LEVEL_OVERRIDE;
+                    }
+                    /* we don't need to set UBIDI_LEVEL_OVERRIDE off for LRE
+                       since this has already been done for newLevel which is
+                       the source for embeddingLevel.
+                     */
+                } else if((embeddingLevel&~UBIDI_LEVEL_OVERRIDE)==UBIDI_MAX_EXPLICIT_LEVEL) {
+                    ++countOver61;
+                } else /* (embeddingLevel&~UBIDI_LEVEL_OVERRIDE)==UBIDI_MAX_EXPLICIT_LEVEL-1 */ {
+                    ++countOver60;
+                }
+                flags|=DIRPROP_FLAG(BN);
+                break;
+            case RLE:
+            case RLO:
+                /* (X2, X4) */
+                newLevel=(UBiDiLevel)(((embeddingLevel&~UBIDI_LEVEL_OVERRIDE)+1)|1); /* least greater odd level */
+                if(newLevel<=UBIDI_MAX_EXPLICIT_LEVEL) {
+                    stack[stackTop]=embeddingLevel;
+                    ++stackTop;
+                    embeddingLevel=newLevel;
+                    if(dirProp==RLO) {
+                        embeddingLevel|=UBIDI_LEVEL_OVERRIDE;
+                    }
+                    /* we don't need to set UBIDI_LEVEL_OVERRIDE off for RLE
+                       since this has already been done for newLevel which is
+                       the source for embeddingLevel.
+                     */
+                } else {
+                    ++countOver61;
+                }
+                flags|=DIRPROP_FLAG(BN);
+                break;
+            case PDF:
+                /* (X7) */
+                /* handle all the overflow cases first */
+                if(countOver61>0) {
+                    --countOver61;
+                } else if(countOver60>0 && (embeddingLevel&~UBIDI_LEVEL_OVERRIDE)!=UBIDI_MAX_EXPLICIT_LEVEL) {
+                    /* handle LRx overflows from level 60 */
+                    --countOver60;
+                } else if(stackTop>0) {
+                    /* this is the pop operation; it also pops level 61 while countOver60>0 */
+                    --stackTop;
+                    embeddingLevel=stack[stackTop];
+                /* } else { (underflow) */
+                }
+                flags|=DIRPROP_FLAG(BN);
+                break;
+            case B:
+                stackTop=0;
+                countOver60=countOver61=0;
+                level=GET_PARALEVEL(pBiDi, i);
+                if((i+1)<length) {
+                    embeddingLevel=GET_PARALEVEL(pBiDi, i+1);
+                    if(!((text[i]==CR) && (text[i+1]==LF))) {
+                        pBiDi->paras[paraIndex++]=i+1;
+                    }
+                }
+                flags|=DIRPROP_FLAG(B);
+                break;
+            case BN:
+                /* BN, LRE, RLE, and PDF are supposed to be removed (X9) */
+                /* they will get their levels set correctly in adjustWSLevels() */
+                flags|=DIRPROP_FLAG(BN);
+                break;
+            default:
+                /* all other types get the "real" level */
+                if(level!=embeddingLevel) {
+                    level=embeddingLevel;
+                    if(level&UBIDI_LEVEL_OVERRIDE) {
+                        flags|=DIRPROP_FLAG_O(level)|DIRPROP_FLAG_MULTI_RUNS;
+                    } else {
+                        flags|=DIRPROP_FLAG_E(level)|DIRPROP_FLAG_MULTI_RUNS;
+                    }
+                }
+                if(!(level&UBIDI_LEVEL_OVERRIDE)) {
+                    flags|=DIRPROP_FLAG(dirProp);
+                }
+                break;
+            }
+
+            /*
+             * We need to set reasonable levels even on BN codes and
+             * explicit codes because we will later look at same-level runs (X10).
+             */
+            levels[i]=level;
+        }
+        if(flags&MASK_EMBEDDING) {
+            flags|=DIRPROP_FLAG_LR(pBiDi->paraLevel);
+        }
+        if(pBiDi->orderParagraphsLTR && (flags&DIRPROP_FLAG(B))) {
+            flags|=DIRPROP_FLAG(L);
+        }
+
+        /* subsequently, ignore the explicit codes and BN (X9) */
+
+        /* again, determine if the text is mixed-directional or single-directional */
+        pBiDi->flags=flags;
+        direction=directionFromFlags(pBiDi);
+    }
+
+    return direction;
+}
+
+/*
+ * Use a pre-specified embedding levels array:
+ *
+ * Adjust the directional properties for overrides (->LEVEL_OVERRIDE),
+ * ignore all explicit codes (X9),
+ * and check all the preset levels.
+ *
+ * Recalculate the flags to have them reflect the real properties
+ * after taking the explicit embeddings into account.
+ */
+static UBiDiDirection
+checkExplicitLevels(UBiDi *pBiDi, UErrorCode *pErrorCode) {
+    const DirProp *dirProps=pBiDi->dirProps;
+    DirProp dirProp;
+    UBiDiLevel *levels=pBiDi->levels;
+    const UChar *text=pBiDi->text;
+
+    int32_t i, length=pBiDi->length;
+    Flags flags=0;  /* collect all directionalities in the text */
+    UBiDiLevel level;
+    uint32_t paraIndex=0;
+
+    for(i=0; i<length; ++i) {
+        level=levels[i];
+        dirProp=NO_CONTEXT_RTL(dirProps[i]);
+        if(level&UBIDI_LEVEL_OVERRIDE) {
+            /* keep the override flag in levels[i] but adjust the flags */
+            level&=~UBIDI_LEVEL_OVERRIDE;     /* make the range check below simpler */
+            flags|=DIRPROP_FLAG_O(level);
+        } else {
+            /* set the flags */
+            flags|=DIRPROP_FLAG_E(level)|DIRPROP_FLAG(dirProp);
+        }
+        if((level<GET_PARALEVEL(pBiDi, i) &&
+            !((0==level)&&(dirProp==B))) ||
+           (UBIDI_MAX_EXPLICIT_LEVEL<level)) {
+            /* level out of bounds */
+            *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+            return UBIDI_LTR;
+        }
+        if((dirProp==B) && ((i+1)<length)) {
+            if(!((text[i]==CR) && (text[i+1]==LF))) {
+                pBiDi->paras[paraIndex++]=i+1;
+            }
+        }
+    }
+    if(flags&MASK_EMBEDDING) {
+        flags|=DIRPROP_FLAG_LR(pBiDi->paraLevel);
+    }
+
+    /* determine if the text is mixed-directional or single-directional */
+    pBiDi->flags=flags;
+    return directionFromFlags(pBiDi);
+}
+
+/******************************************************************
+ The Properties state machine table
+*******************************************************************
+
+ All table cells are 8 bits:
+      bits 0..4:  next state
+      bits 5..7:  action to perform (if > 0)
+
+ Cells may be of format "n" where n represents the next state
+ (except for the rightmost column).
+ Cells may also be of format "s(x,y)" where x represents an action
+ to perform and y represents the next state.
+
+*******************************************************************
+ Definitions and type for properties state table
+*******************************************************************
+*/
+#define IMPTABPROPS_COLUMNS 14
+#define IMPTABPROPS_RES (IMPTABPROPS_COLUMNS - 1)
+#define GET_STATEPROPS(cell) ((cell)&0x1f)
+#define GET_ACTIONPROPS(cell) ((cell)>>5)
+#define s(action, newState) ((uint8_t)(newState+(action<<5)))
+
+static const uint8_t groupProp[] =          /* dirProp regrouped */
+{
+/*  L   R   EN  ES  ET  AN  CS  B   S   WS  ON  LRE LRO AL  RLE RLO PDF NSM BN  */
+    0,  1,  2,  7,  8,  3,  9,  6,  5,  4,  4,  10, 10, 12, 10, 10, 10, 11, 10
+};
+enum { DirProp_L=0, DirProp_R=1, DirProp_EN=2, DirProp_AN=3, DirProp_ON=4, DirProp_S=5, DirProp_B=6 }; /* reduced dirProp */
+
+/******************************************************************
+
+      PROPERTIES  STATE  TABLE
+
+ In table impTabProps,
+      - the ON column regroups ON and WS
+      - the BN column regroups BN, LRE, RLE, LRO, RLO, PDF
+      - the Res column is the reduced property assigned to a run
+
+ Action 1: process current run1, init new run1
+        2: init new run2
+        3: process run1, process run2, init new run1
+        4: process run1, set run1=run2, init new run2
+
+ Notes:
+  1) This table is used in resolveImplicitLevels().
+  2) This table triggers actions when there is a change in the Bidi
+     property of incoming characters (action 1).
+  3) Most such property sequences are processed immediately (in
+     fact, passed to processPropertySeq().
+  4) However, numbers are assembled as one sequence. This means
+     that undefined situations (like CS following digits, until
+     it is known if the next char will be a digit) are held until
+     following chars define them.
+     Example: digits followed by CS, then comes another CS or ON;
+              the digits will be processed, then the CS assigned
+              as the start of an ON sequence (action 3).
+  5) There are cases where more than one sequence must be
+     processed, for instance digits followed by CS followed by L:
+     the digits must be processed as one sequence, and the CS
+     must be processed as an ON sequence, all this before starting
+     assembling chars for the opening L sequence.
+
+
+*/
+static const uint8_t impTabProps[][IMPTABPROPS_COLUMNS] =
+{
+/*                        L ,     R ,    EN ,    AN ,    ON ,     S ,     B ,    ES ,    ET ,    CS ,    BN ,   NSM ,    AL ,  Res */
+/* 0 Init        */ {     1 ,     2 ,     4 ,     5 ,     7 ,    15 ,    17 ,     7 ,     9 ,     7 ,     0 ,     7 ,     3 ,  DirProp_ON },
+/* 1 L           */ {     1 , s(1,2), s(1,4), s(1,5), s(1,7),s(1,15),s(1,17), s(1,7), s(1,9), s(1,7),     1 ,     1 , s(1,3),   DirProp_L },
+/* 2 R           */ { s(1,1),     2 , s(1,4), s(1,5), s(1,7),s(1,15),s(1,17), s(1,7), s(1,9), s(1,7),     2 ,     2 , s(1,3),   DirProp_R },
+/* 3 AL          */ { s(1,1), s(1,2), s(1,6), s(1,6), s(1,8),s(1,16),s(1,17), s(1,8), s(1,8), s(1,8),     3 ,     3 ,     3 ,   DirProp_R },
+/* 4 EN          */ { s(1,1), s(1,2),     4 , s(1,5), s(1,7),s(1,15),s(1,17),s(2,10),    11 ,s(2,10),     4 ,     4 , s(1,3),  DirProp_EN },
+/* 5 AN          */ { s(1,1), s(1,2), s(1,4),     5 , s(1,7),s(1,15),s(1,17), s(1,7), s(1,9),s(2,12),     5 ,     5 , s(1,3),  DirProp_AN },
+/* 6 AL:EN/AN    */ { s(1,1), s(1,2),     6 ,     6 , s(1,8),s(1,16),s(1,17), s(1,8), s(1,8),s(2,13),     6 ,     6 , s(1,3),  DirProp_AN },
+/* 7 ON          */ { s(1,1), s(1,2), s(1,4), s(1,5),     7 ,s(1,15),s(1,17),     7 ,s(2,14),     7 ,     7 ,     7 , s(1,3),  DirProp_ON },
+/* 8 AL:ON       */ { s(1,1), s(1,2), s(1,6), s(1,6),     8 ,s(1,16),s(1,17),     8 ,     8 ,     8 ,     8 ,     8 , s(1,3),  DirProp_ON },
+/* 9 ET          */ { s(1,1), s(1,2),     4 , s(1,5),     7 ,s(1,15),s(1,17),     7 ,     9 ,     7 ,     9 ,     9 , s(1,3),  DirProp_ON },
+/*10 EN+ES/CS    */ { s(3,1), s(3,2),     4 , s(3,5), s(4,7),s(3,15),s(3,17), s(4,7),s(4,14), s(4,7),    10 , s(4,7), s(3,3),  DirProp_EN },
+/*11 EN+ET       */ { s(1,1), s(1,2),     4 , s(1,5), s(1,7),s(1,15),s(1,17), s(1,7),    11 , s(1,7),    11 ,    11 , s(1,3),  DirProp_EN },
+/*12 AN+CS       */ { s(3,1), s(3,2), s(3,4),     5 , s(4,7),s(3,15),s(3,17), s(4,7),s(4,14), s(4,7),    12 , s(4,7), s(3,3),  DirProp_AN },
+/*13 AL:EN/AN+CS */ { s(3,1), s(3,2),     6 ,     6 , s(4,8),s(3,16),s(3,17), s(4,8), s(4,8), s(4,8),    13 , s(4,8), s(3,3),  DirProp_AN },
+/*14 ON+ET       */ { s(1,1), s(1,2), s(4,4), s(1,5),     7 ,s(1,15),s(1,17),     7 ,    14 ,     7 ,    14 ,    14 , s(1,3),  DirProp_ON },
+/*15 S           */ { s(1,1), s(1,2), s(1,4), s(1,5), s(1,7),    15 ,s(1,17), s(1,7), s(1,9), s(1,7),    15 , s(1,7), s(1,3),   DirProp_S },
+/*16 AL:S        */ { s(1,1), s(1,2), s(1,6), s(1,6), s(1,8),    16 ,s(1,17), s(1,8), s(1,8), s(1,8),    16 , s(1,8), s(1,3),   DirProp_S },
+/*17 B           */ { s(1,1), s(1,2), s(1,4), s(1,5), s(1,7),s(1,15),    17 , s(1,7), s(1,9), s(1,7),    17 , s(1,7), s(1,3),   DirProp_B }
+};
+
+/*  we must undef macro s because the levels table have a different
+ *  structure (4 bits for action and 4 bits for next state.
+ */
+#undef s
+
+/******************************************************************
+ The levels state machine tables
+*******************************************************************
+
+ All table cells are 8 bits:
+      bits 0..3:  next state
+      bits 4..7:  action to perform (if > 0)
+
+ Cells may be of format "n" where n represents the next state
+ (except for the rightmost column).
+ Cells may also be of format "s(x,y)" where x represents an action
+ to perform and y represents the next state.
+
+ This format limits each table to 16 states each and to 15 actions.
+
+*******************************************************************
+ Definitions and type for levels state tables
+*******************************************************************
+*/
+#define IMPTABLEVELS_COLUMNS (DirProp_B + 2)
+#define IMPTABLEVELS_RES (IMPTABLEVELS_COLUMNS - 1)
+#define GET_STATE(cell) ((cell)&0x0f)
+#define GET_ACTION(cell) ((cell)>>4)
+#define s(action, newState) ((uint8_t)(newState+(action<<4)))
+
+typedef uint8_t ImpTab[][IMPTABLEVELS_COLUMNS];
+typedef uint8_t ImpAct[];
+
+/* FOOD FOR THOUGHT: each ImpTab should have its associated ImpAct,
+ * instead of having a pair of ImpTab and a pair of ImpAct.
+ */
+typedef struct ImpTabPair {
+    const void * pImpTab[2];
+    const void * pImpAct[2];
+} ImpTabPair;
+
+/******************************************************************
+
+      LEVELS  STATE  TABLES
+
+ In all levels state tables,
+      - state 0 is the initial state
+      - the Res column is the increment to add to the text level
+        for this property sequence.
+
+ The impAct arrays for each table of a pair map the local action
+ numbers of the table to the total list of actions. For instance,
+ action 2 in a given table corresponds to the action number which
+ appears in entry [2] of the impAct array for that table.
+ The first entry of all impAct arrays must be 0.
+
+ Action 1: init conditional sequence
+        2: prepend conditional sequence to current sequence
+        3: set ON sequence to new level - 1
+        4: init EN/AN/ON sequence
+        5: fix EN/AN/ON sequence followed by R
+        6: set previous level sequence to level 2
+
+ Notes:
+  1) These tables are used in processPropertySeq(). The input
+     is property sequences as determined by resolveImplicitLevels.
+  2) Most such property sequences are processed immediately
+     (levels are assigned).
+  3) However, some sequences cannot be assigned a final level till
+     one or more following sequences are received. For instance,
+     ON following an R sequence within an even-level paragraph.
+     If the following sequence is R, the ON sequence will be
+     assigned basic run level+1, and so will the R sequence.
+  4) S is generally handled like ON, since its level will be fixed
+     to paragraph level in adjustWSLevels().
+
+*/
+
+static const ImpTab impTabL_DEFAULT =   /* Even paragraph level */
+/*  In this table, conditional sequences receive the higher possible level
+    until proven otherwise.
+*/
+{
+/*                         L ,     R ,    EN ,    AN ,    ON ,     S ,     B , Res */
+/* 0 : init       */ {     0 ,     1 ,     0 ,     2 ,     0 ,     0 ,     0 ,  0 },
+/* 1 : R          */ {     0 ,     1 ,     3 ,     3 , s(1,4), s(1,4),     0 ,  1 },
+/* 2 : AN         */ {     0 ,     1 ,     0 ,     2 , s(1,5), s(1,5),     0 ,  2 },
+/* 3 : R+EN/AN    */ {     0 ,     1 ,     3 ,     3 , s(1,4), s(1,4),     0 ,  2 },
+/* 4 : R+ON       */ { s(2,0),     1 ,     3 ,     3 ,     4 ,     4 , s(2,0),  1 },
+/* 5 : AN+ON      */ { s(2,0),     1 , s(2,0),     2 ,     5 ,     5 , s(2,0),  1 }
+};
+static const ImpTab impTabR_DEFAULT =   /* Odd  paragraph level */
+/*  In this table, conditional sequences receive the lower possible level
+    until proven otherwise.
+*/
+{
+/*                         L ,     R ,    EN ,    AN ,    ON ,     S ,     B , Res */
+/* 0 : init       */ {     1 ,     0 ,     2 ,     2 ,     0 ,     0 ,     0 ,  0 },
+/* 1 : L          */ {     1 ,     0 ,     1 ,     3 , s(1,4), s(1,4),     0 ,  1 },
+/* 2 : EN/AN      */ {     1 ,     0 ,     2 ,     2 ,     0 ,     0 ,     0 ,  1 },
+/* 3 : L+AN       */ {     1 ,     0 ,     1 ,     3 ,     5 ,     5 ,     0 ,  1 },
+/* 4 : L+ON       */ { s(2,1),     0 , s(2,1),     3 ,     4 ,     4 ,     0 ,  0 },
+/* 5 : L+AN+ON    */ {     1 ,     0 ,     1 ,     3 ,     5 ,     5 ,     0 ,  0 }
+};
+static const ImpAct impAct0 = {0,1,2,3,4,5,6};
+static const ImpTabPair impTab_DEFAULT = {{&impTabL_DEFAULT,
+                                           &impTabR_DEFAULT},
+                                          {&impAct0, &impAct0}};
+
+static const ImpTab impTabL_NUMBERS_SPECIAL =   /* Even paragraph level */
+/*  In this table, conditional sequences receive the higher possible level
+    until proven otherwise.
+*/
+{
+/*                         L ,     R ,    EN ,    AN ,    ON ,     S ,     B , Res */
+/* 0 : init       */ {     0 ,     2 ,    1 ,      1 ,     0 ,     0 ,     0 ,  0 },
+/* 1 : L+EN/AN    */ {     0 ,     2 ,    1 ,      1 ,     0 ,     0 ,     0 ,  2 },
+/* 2 : R          */ {     0 ,     2 ,    4 ,      4 , s(1,3),     0 ,     0 ,  1 },
+/* 3 : R+ON       */ { s(2,0),     2 ,    4 ,      4 ,     3 ,     3 , s(2,0),  1 },
+/* 4 : R+EN/AN    */ {     0 ,     2 ,    4 ,      4 , s(1,3), s(1,3),     0 ,  2 }
+  };
+static const ImpTabPair impTab_NUMBERS_SPECIAL = {{&impTabL_NUMBERS_SPECIAL,
+                                                   &impTabR_DEFAULT},
+                                                  {&impAct0, &impAct0}};
+
+static const ImpTab impTabL_GROUP_NUMBERS_WITH_R =
+/*  In this table, EN/AN+ON sequences receive levels as if associated with R
+    until proven that there is L or sor/eor on both sides. AN is handled like EN.
+*/
+{
+/*                         L ,     R ,    EN ,    AN ,    ON ,     S ,     B , Res */
+/* 0 init         */ {     0 ,     3 , s(1,1), s(1,1),     0 ,     0 ,     0 ,  0 },
+/* 1 EN/AN        */ { s(2,0),     3 ,     1 ,     1 ,     2 , s(2,0), s(2,0),  2 },
+/* 2 EN/AN+ON     */ { s(2,0),     3 ,     1 ,     1 ,     2 , s(2,0), s(2,0),  1 },
+/* 3 R            */ {     0 ,     3 ,     5 ,     5 , s(1,4),     0 ,     0 ,  1 },
+/* 4 R+ON         */ { s(2,0),     3 ,     5 ,     5 ,     4 , s(2,0), s(2,0),  1 },
+/* 5 R+EN/AN      */ {     0 ,     3 ,     5 ,     5 , s(1,4),     0 ,     0 ,  2 }
+};
+static const ImpTab impTabR_GROUP_NUMBERS_WITH_R =
+/*  In this table, EN/AN+ON sequences receive levels as if associated with R
+    until proven that there is L on both sides. AN is handled like EN.
+*/
+{
+/*                         L ,     R ,    EN ,    AN ,    ON ,     S ,     B , Res */
+/* 0 init         */ {     2 ,     0 ,     1 ,     1 ,     0 ,     0 ,     0 ,  0 },
+/* 1 EN/AN        */ {     2 ,     0 ,     1 ,     1 ,     0 ,     0 ,     0 ,  1 },
+/* 2 L            */ {     2 ,     0 , s(1,4), s(1,4), s(1,3),     0 ,     0 ,  1 },
+/* 3 L+ON         */ { s(2,2),     0 ,     4 ,     4 ,     3 ,     0 ,     0 ,  0 },
+/* 4 L+EN/AN      */ { s(2,2),     0 ,     4 ,     4 ,     3 ,     0 ,     0 ,  1 }
+};
+static const ImpTabPair impTab_GROUP_NUMBERS_WITH_R = {
+                        {&impTabL_GROUP_NUMBERS_WITH_R,
+                         &impTabR_GROUP_NUMBERS_WITH_R},
+                        {&impAct0, &impAct0}};
+
+
+static const ImpTab impTabL_INVERSE_NUMBERS_AS_L =
+/*  This table is identical to the Default LTR table except that EN and AN are
+    handled like L.
+*/
+{
+/*                         L ,     R ,    EN ,    AN ,    ON ,     S ,     B , Res */
+/* 0 : init       */ {     0 ,     1 ,     0 ,     0 ,     0 ,     0 ,     0 ,  0 },
+/* 1 : R          */ {     0 ,     1 ,     0 ,     0 , s(1,4), s(1,4),     0 ,  1 },
+/* 2 : AN         */ {     0 ,     1 ,     0 ,     0 , s(1,5), s(1,5),     0 ,  2 },
+/* 3 : R+EN/AN    */ {     0 ,     1 ,     0 ,     0 , s(1,4), s(1,4),     0 ,  2 },
+/* 4 : R+ON       */ { s(2,0),     1 , s(2,0), s(2,0),     4 ,     4 , s(2,0),  1 },
+/* 5 : AN+ON      */ { s(2,0),     1 , s(2,0), s(2,0),     5 ,     5 , s(2,0),  1 }
+};
+static const ImpTab impTabR_INVERSE_NUMBERS_AS_L =
+/*  This table is identical to the Default RTL table except that EN and AN are
+    handled like L.
+*/
+{
+/*                         L ,     R ,    EN ,    AN ,    ON ,     S ,     B , Res */
+/* 0 : init       */ {     1 ,     0 ,     1 ,     1 ,     0 ,     0 ,     0 ,  0 },
+/* 1 : L          */ {     1 ,     0 ,     1 ,     1 , s(1,4), s(1,4),     0 ,  1 },
+/* 2 : EN/AN      */ {     1 ,     0 ,     1 ,     1 ,     0 ,     0 ,     0 ,  1 },
+/* 3 : L+AN       */ {     1 ,     0 ,     1 ,     1 ,     5 ,     5 ,     0 ,  1 },
+/* 4 : L+ON       */ { s(2,1),     0 , s(2,1), s(2,1),     4 ,     4 ,     0 ,  0 },
+/* 5 : L+AN+ON    */ {     1 ,     0 ,     1 ,     1 ,     5 ,     5 ,     0 ,  0 }
+};
+static const ImpTabPair impTab_INVERSE_NUMBERS_AS_L = {
+                        {&impTabL_INVERSE_NUMBERS_AS_L,
+                         &impTabR_INVERSE_NUMBERS_AS_L},
+                        {&impAct0, &impAct0}};
+
+static const ImpTab impTabR_INVERSE_LIKE_DIRECT =   /* Odd  paragraph level */
+/*  In this table, conditional sequences receive the lower possible level
+    until proven otherwise.
+*/
+{
+/*                         L ,     R ,    EN ,    AN ,    ON ,     S ,     B , Res */
+/* 0 : init       */ {     1 ,     0 ,     2 ,     2 ,     0 ,     0 ,     0 ,  0 },
+/* 1 : L          */ {     1 ,     0 ,     1 ,     2 , s(1,3), s(1,3),     0 ,  1 },
+/* 2 : EN/AN      */ {     1 ,     0 ,     2 ,     2 ,     0 ,     0 ,     0 ,  1 },
+/* 3 : L+ON       */ { s(2,1), s(3,0),     6 ,     4 ,     3 ,     3 , s(3,0),  0 },
+/* 4 : L+ON+AN    */ { s(2,1), s(3,0),     6 ,     4 ,     5 ,     5 , s(3,0),  3 },
+/* 5 : L+AN+ON    */ { s(2,1), s(3,0),     6 ,     4 ,     5 ,     5 , s(3,0),  2 },
+/* 6 : L+ON+EN    */ { s(2,1), s(3,0),     6 ,     4 ,     3 ,     3 , s(3,0),  1 }
+};
+static const ImpAct impAct1 = {0,1,11,12};
+/* FOOD FOR THOUGHT: in LTR table below, check case "JKL 123abc"
+ */
+static const ImpTabPair impTab_INVERSE_LIKE_DIRECT = {
+                        {&impTabL_DEFAULT,
+                         &impTabR_INVERSE_LIKE_DIRECT},
+                        {&impAct0, &impAct1}};
+
+static const ImpTab impTabL_INVERSE_LIKE_DIRECT_WITH_MARKS =
+/*  The case handled in this table is (visually):  R EN L
+*/
+{
+/*                         L ,     R ,    EN ,    AN ,    ON ,     S ,     B , Res */
+/* 0 : init       */ {     0 , s(6,3),     0 ,     1 ,     0 ,     0 ,     0 ,  0 },
+/* 1 : L+AN       */ {     0 , s(6,3),     0 ,     1 , s(1,2), s(3,0),     0 ,  4 },
+/* 2 : L+AN+ON    */ { s(2,0), s(6,3), s(2,0),     1 ,     2 , s(3,0), s(2,0),  3 },
+/* 3 : R          */ {     0 , s(6,3), s(5,5), s(5,6), s(1,4), s(3,0),     0 ,  3 },
+/* 4 : R+ON       */ { s(3,0), s(4,3), s(5,5), s(5,6),     4 , s(3,0), s(3,0),  3 },
+/* 5 : R+EN       */ { s(3,0), s(4,3),     5 , s(5,6), s(1,4), s(3,0), s(3,0),  4 },
+/* 6 : R+AN       */ { s(3,0), s(4,3), s(5,5),     6 , s(1,4), s(3,0), s(3,0),  4 }
+};
+static const ImpTab impTabR_INVERSE_LIKE_DIRECT_WITH_MARKS =
+/*  The cases handled in this table are (visually):  R EN L
+                                                     R L AN L
+*/
+{
+/*                         L ,     R ,    EN ,    AN ,    ON ,     S ,     B , Res */
+/* 0 : init       */ { s(1,3),     0 ,     1 ,     1 ,     0 ,     0 ,     0 ,  0 },
+/* 1 : R+EN/AN    */ { s(2,3),     0 ,     1 ,     1 ,     2 , s(4,0),     0 ,  1 },
+/* 2 : R+EN/AN+ON */ { s(2,3),     0 ,     1 ,     1 ,     2 , s(4,0),     0 ,  0 },
+/* 3 : L          */ {     3 ,     0 ,     3 , s(3,6), s(1,4), s(4,0),     0 ,  1 },
+/* 4 : L+ON       */ { s(5,3), s(4,0),     5 , s(3,6),     4 , s(4,0), s(4,0),  0 },
+/* 5 : L+ON+EN    */ { s(5,3), s(4,0),     5 , s(3,6),     4 , s(4,0), s(4,0),  1 },
+/* 6 : L+AN       */ { s(5,3), s(4,0),     6 ,     6 ,     4 , s(4,0), s(4,0),  3 }
+};
+static const ImpAct impAct2 = {0,1,7,8,9,10};
+static const ImpTabPair impTab_INVERSE_LIKE_DIRECT_WITH_MARKS = {
+                        {&impTabL_INVERSE_LIKE_DIRECT_WITH_MARKS,
+                         &impTabR_INVERSE_LIKE_DIRECT_WITH_MARKS},
+                        {&impAct0, &impAct2}};
+
+static const ImpTabPair impTab_INVERSE_FOR_NUMBERS_SPECIAL = {
+                        {&impTabL_NUMBERS_SPECIAL,
+                         &impTabR_INVERSE_LIKE_DIRECT},
+                        {&impAct0, &impAct1}};
+
+static const ImpTab impTabL_INVERSE_FOR_NUMBERS_SPECIAL_WITH_MARKS =
+/*  The case handled in this table is (visually):  R EN L
+*/
+{
+/*                         L ,     R ,    EN ,    AN ,    ON ,     S ,     B , Res */
+/* 0 : init       */ {     0 , s(6,2),     1 ,     1 ,     0 ,     0 ,     0 ,  0 },
+/* 1 : L+EN/AN    */ {     0 , s(6,2),     1 ,     1 ,     0 , s(3,0),     0 ,  4 },
+/* 2 : R          */ {     0 , s(6,2), s(5,4), s(5,4), s(1,3), s(3,0),     0 ,  3 },
+/* 3 : R+ON       */ { s(3,0), s(4,2), s(5,4), s(5,4),     3 , s(3,0), s(3,0),  3 },
+/* 4 : R+EN/AN    */ { s(3,0), s(4,2),     4 ,     4 , s(1,3), s(3,0), s(3,0),  4 }
+};
+static const ImpTabPair impTab_INVERSE_FOR_NUMBERS_SPECIAL_WITH_MARKS = {
+                        {&impTabL_INVERSE_FOR_NUMBERS_SPECIAL_WITH_MARKS,
+                         &impTabR_INVERSE_LIKE_DIRECT_WITH_MARKS},
+                        {&impAct0, &impAct2}};
+
+#undef s
+
+typedef struct {
+    const ImpTab * pImpTab;             /* level table pointer          */
+    const ImpAct * pImpAct;             /* action map array             */
+    int32_t startON;                    /* start of ON sequence         */
+    int32_t startL2EN;                  /* start of level 2 sequence    */
+    int32_t lastStrongRTL;              /* index of last found R or AL  */
+    int32_t state;                      /* current state                */
+    UBiDiLevel runLevel;                /* run level before implicit solving */
+} LevState;
+
+/*------------------------------------------------------------------------*/
+
+static void
+addPoint(UBiDi *pBiDi, int32_t pos, int32_t flag)
+  /* param pos:     position where to insert
+     param flag:    one of LRM_BEFORE, LRM_AFTER, RLM_BEFORE, RLM_AFTER
+  */
+{
+#define FIRSTALLOC  10
+    Point point;
+    InsertPoints * pInsertPoints=&(pBiDi->insertPoints);
+
+    if (pInsertPoints->capacity == 0)
+    {
+        pInsertPoints->points=uprv_malloc(sizeof(Point)*FIRSTALLOC);
+        if (pInsertPoints->points == NULL)
+        {
+            pInsertPoints->errorCode=U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+        pInsertPoints->capacity=FIRSTALLOC;
+    }
+    if (pInsertPoints->size >= pInsertPoints->capacity) /* no room for new point */
+    {
+        void * savePoints=pInsertPoints->points;
+        pInsertPoints->points=uprv_realloc(pInsertPoints->points,
+                                           pInsertPoints->capacity*2*sizeof(Point));
+        if (pInsertPoints->points == NULL)
+        {
+            pInsertPoints->points=savePoints;
+            pInsertPoints->errorCode=U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+        else  pInsertPoints->capacity*=2;
+    }
+    point.pos=pos;
+    point.flag=flag;
+    pInsertPoints->points[pInsertPoints->size]=point;
+    pInsertPoints->size++;
+#undef FIRSTALLOC
+}
+
+/* perform rules (Wn), (Nn), and (In) on a run of the text ------------------ */
+
+/*
+ * This implementation of the (Wn) rules applies all rules in one pass.
+ * In order to do so, it needs a look-ahead of typically 1 character
+ * (except for W5: sequences of ET) and keeps track of changes
+ * in a rule Wp that affect a later Wq (p<q).
+ *
+ * The (Nn) and (In) rules are also performed in that same single loop,
+ * but effectively one iteration behind for white space.
+ *
+ * Since all implicit rules are performed in one step, it is not necessary
+ * to actually store the intermediate directional properties in dirProps[].
+ */
+
+static void
+processPropertySeq(UBiDi *pBiDi, LevState *pLevState, uint8_t _prop,
+                   int32_t start, int32_t limit) {
+    uint8_t cell, oldStateSeq, actionSeq;
+    const ImpTab * pImpTab=pLevState->pImpTab;
+    const ImpAct * pImpAct=pLevState->pImpAct;
+    UBiDiLevel * levels=pBiDi->levels;
+    UBiDiLevel level, addLevel;
+    InsertPoints * pInsertPoints;
+    int32_t start0, k;
+
+    start0=start;                           /* save original start position */
+    oldStateSeq=(uint8_t)pLevState->state;
+    cell=(*pImpTab)[oldStateSeq][_prop];
+    pLevState->state=GET_STATE(cell);       /* isolate the new state */
+    actionSeq=(*pImpAct)[GET_ACTION(cell)]; /* isolate the action */
+    addLevel=(*pImpTab)[pLevState->state][IMPTABLEVELS_RES];
+
+    if(actionSeq) {
+        switch(actionSeq) {
+        case 1:                         /* init ON seq */
+            pLevState->startON=start0;
+            break;
+
+        case 2:                         /* prepend ON seq to current seq */
+            start=pLevState->startON;
+            break;
+
+        case 3:                         /* L or S after possible relevant EN/AN */
+            /* check if we had EN after R/AL */
+            if (pLevState->startL2EN >= 0) {
+                addPoint(pBiDi, pLevState->startL2EN, LRM_BEFORE);
+            }
+            pLevState->startL2EN=-1;  /* not within previous if since could also be -2 */
+            /* check if we had any relevant EN/AN after R/AL */
+            pInsertPoints=&(pBiDi->insertPoints);
+            if ((pInsertPoints->capacity == 0) ||
+                (pInsertPoints->size <= pInsertPoints->confirmed))
+            {
+                /* nothing, just clean up */
+                pLevState->lastStrongRTL=-1;
+                /* check if we have a pending conditional segment */
+                level=(*pImpTab)[oldStateSeq][IMPTABLEVELS_RES];
+                if ((level & 1) && (pLevState->startON > 0)) {  /* after ON */
+                    start=pLevState->startON;   /* reset to basic run level */
+                }
+                if (_prop == DirProp_S)                /* add LRM before S */
+                {
+                    addPoint(pBiDi, start0, LRM_BEFORE);
+                    pInsertPoints->confirmed=pInsertPoints->size;
+                }
+                break;
+            }
+            /* reset previous RTL cont to level for LTR text */
+            for (k=pLevState->lastStrongRTL+1; k<start0; k++)
+            {
+                /* reset odd level, leave runLevel+2 as is */
+                levels[k]=(levels[k] - 2) & ~1;
+            }
+            /* mark insert points as confirmed */
+            pInsertPoints->confirmed=pInsertPoints->size;
+            pLevState->lastStrongRTL=-1;
+            if (_prop == DirProp_S)            /* add LRM before S */
+            {
+                addPoint(pBiDi, start0, LRM_BEFORE);
+                pInsertPoints->confirmed=pInsertPoints->size;
+            }
+            break;
+
+        case 4:                         /* R/AL after possible relevant EN/AN */
+            /* just clean up */
+            pInsertPoints=&(pBiDi->insertPoints);
+            if (pInsertPoints->capacity > 0)
+                /* remove all non confirmed insert points */
+                pInsertPoints->size=pInsertPoints->confirmed;
+            pLevState->startON=-1;
+            pLevState->startL2EN=-1;
+            pLevState->lastStrongRTL=limit - 1;
+            break;
+
+        case 5:                         /* EN/AN after R/AL + possible cont */
+            /* check for real AN */
+            if ((_prop == DirProp_AN) && (NO_CONTEXT_RTL(pBiDi->dirProps[start0]) == AN) &&
+                (pBiDi->reorderingMode!=UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL))
+            {
+                /* real AN */
+                if (pLevState->startL2EN == -1) /* if no relevant EN already found */
+                {
+                    /* just note the righmost digit as a strong RTL */
+                    pLevState->lastStrongRTL=limit - 1;
+                    break;
+                }
+                if (pLevState->startL2EN >= 0)  /* after EN, no AN */
+                {
+                    addPoint(pBiDi, pLevState->startL2EN, LRM_BEFORE);
+                    pLevState->startL2EN=-2;
+                }
+                /* note AN */
+                addPoint(pBiDi, start0, LRM_BEFORE);
+                break;
+            }
+            /* if first EN/AN after R/AL */
+            if (pLevState->startL2EN == -1) {
+                pLevState->startL2EN=start0;
+            }
+            break;
+
+        case 6:                         /* note location of latest R/AL */
+            pLevState->lastStrongRTL=limit - 1;
+            pLevState->startON=-1;
+            break;
+
+        case 7:                         /* L after R+ON/EN/AN */
+            /* include possible adjacent number on the left */
+            for (k=start0-1; k>=0 && !(levels[k]&1); k--);
+            if(k>=0) {
+                addPoint(pBiDi, k, RLM_BEFORE);             /* add RLM before */
+                pInsertPoints=&(pBiDi->insertPoints);
+                pInsertPoints->confirmed=pInsertPoints->size;   /* confirm it */
+            }
+            pLevState->startON=start0;
+            break;
+
+        case 8:                         /* AN after L */
+            /* AN numbers between L text on both sides may be trouble. */
+            /* tentatively bracket with LRMs; will be confirmed if followed by L */
+            addPoint(pBiDi, start0, LRM_BEFORE);    /* add LRM before */
+            addPoint(pBiDi, start0, LRM_AFTER);     /* add LRM after  */
+            break;
+
+        case 9:                         /* R after L+ON/EN/AN */
+            /* false alert, infirm LRMs around previous AN */
+            pInsertPoints=&(pBiDi->insertPoints);
+            pInsertPoints->size=pInsertPoints->confirmed;
+            if (_prop == DirProp_S)            /* add RLM before S */
+            {
+                addPoint(pBiDi, start0, RLM_BEFORE);
+                pInsertPoints->confirmed=pInsertPoints->size;
+            }
+            break;
+
+        case 10:                        /* L after L+ON/AN */
+            level=pLevState->runLevel + addLevel;
+            for(k=pLevState->startON; k<start0; k++) {
+                if (levels[k]<level)
+                    levels[k]=level;
+            }
+            pInsertPoints=&(pBiDi->insertPoints);
+            pInsertPoints->confirmed=pInsertPoints->size;   /* confirm inserts */
+            pLevState->startON=start0;
+            break;
+
+        case 11:                        /* L after L+ON+EN/AN/ON */
+            level=pLevState->runLevel;
+            for(k=start0-1; k>=pLevState->startON; k--) {
+                if(levels[k]==level+3) {
+                    while(levels[k]==level+3) {
+                        levels[k--]-=2;
+                    }
+                    while(levels[k]==level) {
+                        k--;
+                    }
+                }
+                if(levels[k]==level+2) {
+                    levels[k]=level;
+                    continue;
+                }
+                levels[k]=level+1;
+            }
+            break;
+
+        case 12:                        /* R after L+ON+EN/AN/ON */
+            level=pLevState->runLevel+1;
+            for(k=start0-1; k>=pLevState->startON; k--) {
+                if(levels[k]>level) {
+                    levels[k]-=2;
+                }
+            }
+            break;
+
+        default:                        /* we should never get here */
+            U_ASSERT(FALSE);
+            break;
+        }
+    }
+    if((addLevel) || (start < start0)) {
+        level=pLevState->runLevel + addLevel;
+        for(k=start; k<limit; k++) {
+            levels[k]=level;
+        }
+    }
+}
+
+static void
+resolveImplicitLevels(UBiDi *pBiDi,
+                      int32_t start, int32_t limit,
+                      DirProp sor, DirProp eor) {
+    const DirProp *dirProps=pBiDi->dirProps;
+
+    LevState levState;
+    int32_t i, start1, start2;
+    uint8_t oldStateImp, stateImp, actionImp;
+    uint8_t gprop, resProp, cell;
+    UBool inverseRTL;
+    DirProp nextStrongProp=R;
+    int32_t nextStrongPos=-1;
+
+    levState.startON = -1;  /* silence gcc flow analysis */
+
+    /* check for RTL inverse BiDi mode */
+    /* FOOD FOR THOUGHT: in case of RTL inverse BiDi, it would make sense to
+     * loop on the text characters from end to start.
+     * This would need a different properties state table (at least different
+     * actions) and different levels state tables (maybe very similar to the
+     * LTR corresponding ones.
+     */
+    inverseRTL=(UBool)
+        ((start<pBiDi->lastArabicPos) && (GET_PARALEVEL(pBiDi, start) & 1) &&
+         (pBiDi->reorderingMode==UBIDI_REORDER_INVERSE_LIKE_DIRECT  ||
+          pBiDi->reorderingMode==UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL));
+    /* initialize for levels state table */
+    levState.startL2EN=-1;              /* used for INVERSE_LIKE_DIRECT_WITH_MARKS */
+    levState.lastStrongRTL=-1;          /* used for INVERSE_LIKE_DIRECT_WITH_MARKS */
+    levState.state=0;
+    levState.runLevel=pBiDi->levels[start];
+    levState.pImpTab=(const ImpTab*)((pBiDi->pImpTabPair)->pImpTab)[levState.runLevel&1];
+    levState.pImpAct=(const ImpAct*)((pBiDi->pImpTabPair)->pImpAct)[levState.runLevel&1];
+    processPropertySeq(pBiDi, &levState, sor, start, start);
+    /* initialize for property state table */
+    if(NO_CONTEXT_RTL(dirProps[start])==NSM) {
+        stateImp = 1 + sor;
+    } else {
+        stateImp=0;
+    }
+    start1=start;
+    start2=start;
+
+    for(i=start; i<=limit; i++) {
+        if(i>=limit) {
+            gprop=eor;
+        } else {
+            DirProp prop, prop1;
+            prop=NO_CONTEXT_RTL(dirProps[i]);
+            if(inverseRTL) {
+                if(prop==AL) {
+                    /* AL before EN does not make it AN */
+                    prop=R;
+                } else if(prop==EN) {
+                    if(nextStrongPos<=i) {
+                        /* look for next strong char (L/R/AL) */
+                        int32_t j;
+                        nextStrongProp=R;   /* set default */
+                        nextStrongPos=limit;
+                        for(j=i+1; j<limit; j++) {
+                            prop1=NO_CONTEXT_RTL(dirProps[j]);
+                            if(prop1==L || prop1==R || prop1==AL) {
+                                nextStrongProp=prop1;
+                                nextStrongPos=j;
+                                break;
+                            }
+                        }
+                    }
+                    if(nextStrongProp==AL) {
+                        prop=AN;
+                    }
+                }
+            }
+            gprop=groupProp[prop];
+        }
+        oldStateImp=stateImp;
+        cell=impTabProps[oldStateImp][gprop];
+        stateImp=GET_STATEPROPS(cell);      /* isolate the new state */
+        actionImp=GET_ACTIONPROPS(cell);    /* isolate the action */
+        if((i==limit) && (actionImp==0)) {
+            /* there is an unprocessed sequence if its property == eor   */
+            actionImp=1;                    /* process the last sequence */
+        }
+        if(actionImp) {
+            resProp=impTabProps[oldStateImp][IMPTABPROPS_RES];
+            switch(actionImp) {
+            case 1:             /* process current seq1, init new seq1 */
+                processPropertySeq(pBiDi, &levState, resProp, start1, i);
+                start1=i;
+                break;
+            case 2:             /* init new seq2 */
+                start2=i;
+                break;
+            case 3:             /* process seq1, process seq2, init new seq1 */
+                processPropertySeq(pBiDi, &levState, resProp, start1, start2);
+                processPropertySeq(pBiDi, &levState, DirProp_ON, start2, i);
+                start1=i;
+                break;
+            case 4:             /* process seq1, set seq1=seq2, init new seq2 */
+                processPropertySeq(pBiDi, &levState, resProp, start1, start2);
+                start1=start2;
+                start2=i;
+                break;
+            default:            /* we should never get here */
+                U_ASSERT(FALSE);
+                break;
+            }
+        }
+    }
+    /* flush possible pending sequence, e.g. ON */
+    processPropertySeq(pBiDi, &levState, eor, limit, limit);
+}
+
+/* perform (L1) and (X9) ---------------------------------------------------- */
+
+/*
+ * Reset the embedding levels for some non-graphic characters (L1).
+ * This function also sets appropriate levels for BN, and
+ * explicit embedding types that are supposed to have been removed
+ * from the paragraph in (X9).
+ */
+static void
+adjustWSLevels(UBiDi *pBiDi) {
+    const DirProp *dirProps=pBiDi->dirProps;
+    UBiDiLevel *levels=pBiDi->levels;
+    int32_t i;
+
+    if(pBiDi->flags&MASK_WS) {
+        UBool orderParagraphsLTR=pBiDi->orderParagraphsLTR;
+        Flags flag;
+
+        i=pBiDi->trailingWSStart;
+        while(i>0) {
+            /* reset a sequence of WS/BN before eop and B/S to the paragraph paraLevel */
+            while(i>0 && (flag=DIRPROP_FLAG_NC(dirProps[--i]))&MASK_WS) {
+                if(orderParagraphsLTR&&(flag&DIRPROP_FLAG(B))) {
+                    levels[i]=0;
+                } else {
+                    levels[i]=GET_PARALEVEL(pBiDi, i);
+                }
+            }
+
+            /* reset BN to the next character's paraLevel until B/S, which restarts above loop */
+            /* here, i+1 is guaranteed to be <length */
+            while(i>0) {
+                flag=DIRPROP_FLAG_NC(dirProps[--i]);
+                if(flag&MASK_BN_EXPLICIT) {
+                    levels[i]=levels[i+1];
+                } else if(orderParagraphsLTR&&(flag&DIRPROP_FLAG(B))) {
+                    levels[i]=0;
+                    break;
+                } else if(flag&MASK_B_S) {
+                    levels[i]=GET_PARALEVEL(pBiDi, i);
+                    break;
+                }
+            }
+        }
+    }
+}
+
+#define BIDI_MIN(x, y)   ((x)<(y) ? (x) : (y))
+#define BIDI_ABS(x)      ((x)>=0  ? (x) : (-(x)))
+static void
+setParaRunsOnly(UBiDi *pBiDi, const UChar *text, int32_t length,
+                UBiDiLevel paraLevel, UErrorCode *pErrorCode) {
+    void *runsOnlyMemory;
+    int32_t *visualMap;
+    UChar *visualText;
+    int32_t saveLength, saveTrailingWSStart;
+    const UBiDiLevel *levels;
+    UBiDiLevel *saveLevels;
+    UBiDiDirection saveDirection;
+    UBool saveMayAllocateText;
+    Run *runs;
+    int32_t visualLength, i, j, visualStart, logicalStart,
+            runCount, runLength, addedRuns, insertRemove,
+            start, limit, step, indexOddBit, logicalPos,
+            index0, index1;
+    uint32_t saveOptions;
+
+    pBiDi->reorderingMode=UBIDI_REORDER_DEFAULT;
+    if(length==0) {
+        ubidi_setPara(pBiDi, text, length, paraLevel, NULL, pErrorCode);
+        goto cleanup3;
+    }
+    /* obtain memory for mapping table and visual text */
+    runsOnlyMemory=uprv_malloc(length*(sizeof(int32_t)+sizeof(UChar)+sizeof(UBiDiLevel)));
+    if(runsOnlyMemory==NULL) {
+        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+        goto cleanup3;
+    }
+    visualMap=runsOnlyMemory;
+    visualText=(UChar *)&visualMap[length];
+    saveLevels=(UBiDiLevel *)&visualText[length];
+    saveOptions=pBiDi->reorderingOptions;
+    if(saveOptions & UBIDI_OPTION_INSERT_MARKS) {
+        pBiDi->reorderingOptions&=~UBIDI_OPTION_INSERT_MARKS;
+        pBiDi->reorderingOptions|=UBIDI_OPTION_REMOVE_CONTROLS;
+    }
+    paraLevel&=1;                       /* accept only 0 or 1 */
+    ubidi_setPara(pBiDi, text, length, paraLevel, NULL, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        goto cleanup3;
+    }
+    /* we cannot access directly pBiDi->levels since it is not yet set if
+     * direction is not MIXED
+     */
+    levels=ubidi_getLevels(pBiDi, pErrorCode);
+    uprv_memcpy(saveLevels, levels, pBiDi->length*sizeof(UBiDiLevel));
+    saveTrailingWSStart=pBiDi->trailingWSStart;
+    saveLength=pBiDi->length;
+    saveDirection=pBiDi->direction;
+
+    /* FOOD FOR THOUGHT: instead of writing the visual text, we could use
+     * the visual map and the dirProps array to drive the second call
+     * to ubidi_setPara (but must make provision for possible removal of
+     * BiDi controls.  Alternatively, only use the dirProps array via
+     * customized classifier callback.
+     */
+    visualLength=ubidi_writeReordered(pBiDi, visualText, length,
+                                      UBIDI_DO_MIRRORING, pErrorCode);
+    ubidi_getVisualMap(pBiDi, visualMap, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        goto cleanup2;
+    }
+    pBiDi->reorderingOptions=saveOptions;
+
+    pBiDi->reorderingMode=UBIDI_REORDER_INVERSE_LIKE_DIRECT;
+    paraLevel^=1;
+    /* Because what we did with reorderingOptions, visualText may be shorter
+     * than the original text. But we don't want the levels memory to be
+     * reallocated shorter than the original length, since we need to restore
+     * the levels as after the first call to ubidi_setpara() before returning.
+     * We will force mayAllocateText to FALSE before the second call to
+     * ubidi_setpara(), and will restore it afterwards.
+     */
+    saveMayAllocateText=pBiDi->mayAllocateText;
+    pBiDi->mayAllocateText=FALSE;
+    ubidi_setPara(pBiDi, visualText, visualLength, paraLevel, NULL, pErrorCode);
+    pBiDi->mayAllocateText=saveMayAllocateText;
+    ubidi_getRuns(pBiDi, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        goto cleanup1;
+    }
+    /* check if some runs must be split, count how many splits */
+    addedRuns=0;
+    runCount=pBiDi->runCount;
+    runs=pBiDi->runs;
+    visualStart=0;
+    for(i=0; i<runCount; i++, visualStart+=runLength) {
+        runLength=runs[i].visualLimit-visualStart;
+        if(runLength<2) {
+            continue;
+        }
+        logicalStart=GET_INDEX(runs[i].logicalStart);
+        for(j=logicalStart+1; j<logicalStart+runLength; j++) {
+            index0=visualMap[j];
+            index1=visualMap[j-1];
+            if((BIDI_ABS(index0-index1)!=1) || (saveLevels[index0]!=saveLevels[index1])) {
+                addedRuns++;
+            }
+        }
+    }
+    if(addedRuns) {
+        if(getRunsMemory(pBiDi, runCount+addedRuns)) {
+            if(runCount==1) {
+                /* because we switch from UBiDi.simpleRuns to UBiDi.runs */
+                pBiDi->runsMemory[0]=runs[0];
+            }
+            runs=pBiDi->runs=pBiDi->runsMemory;
+            pBiDi->runCount+=addedRuns;
+        } else {
+            goto cleanup1;
+        }
+    }
+    /* split runs which are not consecutive in source text */
+    for(i=runCount-1; i>=0; i--) {
+        runLength= i==0 ? runs[0].visualLimit :
+                          runs[i].visualLimit-runs[i-1].visualLimit;
+        logicalStart=runs[i].logicalStart;
+        indexOddBit=GET_ODD_BIT(logicalStart);
+        logicalStart=GET_INDEX(logicalStart);
+        if(runLength<2) {
+            if(addedRuns) {
+                runs[i+addedRuns]=runs[i];
+            }
+            logicalPos=visualMap[logicalStart];
+            runs[i+addedRuns].logicalStart=MAKE_INDEX_ODD_PAIR(logicalPos,
+                                            saveLevels[logicalPos]^indexOddBit);
+            continue;
+        }
+        if(indexOddBit) {
+            start=logicalStart;
+            limit=logicalStart+runLength-1;
+            step=1;
+        } else {
+            start=logicalStart+runLength-1;
+            limit=logicalStart;
+            step=-1;
+        }
+        for(j=start; j!=limit; j+=step) {
+            index0=visualMap[j];
+            index1=visualMap[j+step];
+            if((BIDI_ABS(index0-index1)!=1) || (saveLevels[index0]!=saveLevels[index1])) {
+                logicalPos=BIDI_MIN(visualMap[start], index0);
+                runs[i+addedRuns].logicalStart=MAKE_INDEX_ODD_PAIR(logicalPos,
+                                            saveLevels[logicalPos]^indexOddBit);
+                runs[i+addedRuns].visualLimit=runs[i].visualLimit;
+                runs[i].visualLimit-=BIDI_ABS(j-start)+1;
+                insertRemove=runs[i].insertRemove&(LRM_AFTER|RLM_AFTER);
+                runs[i+addedRuns].insertRemove=insertRemove;
+                runs[i].insertRemove&=~insertRemove;
+                start=j+step;
+                addedRuns--;
+            }
+        }
+        if(addedRuns) {
+            runs[i+addedRuns]=runs[i];
+        }
+        logicalPos=BIDI_MIN(visualMap[start], visualMap[limit]);
+        runs[i+addedRuns].logicalStart=MAKE_INDEX_ODD_PAIR(logicalPos,
+                                            saveLevels[logicalPos]^indexOddBit);
+    }
+
+  cleanup1:
+    /* restore initial paraLevel */
+    pBiDi->paraLevel^=1;
+  cleanup2:
+    /* restore real text */
+    pBiDi->text=text;
+    pBiDi->length=saveLength;
+    pBiDi->originalLength=length;
+    pBiDi->direction=saveDirection;
+    /* the saved levels should never excess levelsSize, but we check anyway */
+    if(saveLength>pBiDi->levelsSize) {
+        saveLength=pBiDi->levelsSize;
+    }
+    uprv_memcpy(pBiDi->levels, saveLevels, saveLength*sizeof(UBiDiLevel));
+    pBiDi->trailingWSStart=saveTrailingWSStart;
+    /* free memory for mapping table and visual text */
+    uprv_free(runsOnlyMemory);
+    if(pBiDi->runCount>1) {
+        pBiDi->direction=UBIDI_MIXED;
+    }
+  cleanup3:
+    pBiDi->reorderingMode=UBIDI_REORDER_RUNS_ONLY;
+}
+
+/* ubidi_setPara ------------------------------------------------------------ */
+
+U_CAPI void U_EXPORT2
+ubidi_setPara(UBiDi *pBiDi, const UChar *text, int32_t length,
+              UBiDiLevel paraLevel, UBiDiLevel *embeddingLevels,
+              UErrorCode *pErrorCode) {
+    UBiDiDirection direction;
+
+    /* check the argument values */
+    RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrorCode);
+    if(pBiDi==NULL || text==NULL || length<-1 ||
+       (paraLevel>UBIDI_MAX_EXPLICIT_LEVEL && paraLevel<UBIDI_DEFAULT_LTR)) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    if(length==-1) {
+        length=u_strlen(text);
+    }
+
+    /* special treatment for RUNS_ONLY mode */
+    if(pBiDi->reorderingMode==UBIDI_REORDER_RUNS_ONLY) {
+        setParaRunsOnly(pBiDi, text, length, paraLevel, pErrorCode);
+        return;
+    }
+
+    /* initialize the UBiDi structure */
+    pBiDi->pParaBiDi=NULL;          /* mark unfinished setPara */
+    pBiDi->text=text;
+    pBiDi->length=pBiDi->originalLength=pBiDi->resultLength=length;
+    pBiDi->paraLevel=paraLevel;
+    pBiDi->direction=UBIDI_LTR;
+    pBiDi->paraCount=1;
+
+    pBiDi->dirProps=NULL;
+    pBiDi->levels=NULL;
+    pBiDi->runs=NULL;
+    pBiDi->insertPoints.size=0;         /* clean up from last call */
+    pBiDi->insertPoints.confirmed=0;    /* clean up from last call */
+
+    /*
+     * Save the original paraLevel if contextual; otherwise, set to 0.
+     */
+    if(IS_DEFAULT_LEVEL(paraLevel)) {
+        pBiDi->defaultParaLevel=paraLevel;
+    } else {
+        pBiDi->defaultParaLevel=0;
+    }
+
+    if(length==0) {
+        /*
+         * For an empty paragraph, create a UBiDi object with the paraLevel and
+         * the flags and the direction set but without allocating zero-length arrays.
+         * There is nothing more to do.
+         */
+        if(IS_DEFAULT_LEVEL(paraLevel)) {
+            pBiDi->paraLevel&=1;
+            pBiDi->defaultParaLevel=0;
+        }
+        if(paraLevel&1) {
+            pBiDi->flags=DIRPROP_FLAG(R);
+            pBiDi->direction=UBIDI_RTL;
+        } else {
+            pBiDi->flags=DIRPROP_FLAG(L);
+            pBiDi->direction=UBIDI_LTR;
+        }
+
+        pBiDi->runCount=0;
+        pBiDi->paraCount=0;
+        pBiDi->pParaBiDi=pBiDi;         /* mark successful setPara */
+        return;
+    }
+
+    pBiDi->runCount=-1;
+
+    /*
+     * Get the directional properties,
+     * the flags bit-set, and
+     * determine the paragraph level if necessary.
+     */
+    if(getDirPropsMemory(pBiDi, length)) {
+        pBiDi->dirProps=pBiDi->dirPropsMemory;
+        getDirProps(pBiDi);
+    } else {
+        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+        return;
+    }
+    /* the processed length may have changed if UBIDI_OPTION_STREAMING */
+    length= pBiDi->length;
+    pBiDi->trailingWSStart=length;  /* the levels[] will reflect the WS run */
+    /* allocate paras memory */
+    if(pBiDi->paraCount>1) {
+        if(getInitialParasMemory(pBiDi, pBiDi->paraCount)) {
+            pBiDi->paras=pBiDi->parasMemory;
+            pBiDi->paras[pBiDi->paraCount-1]=length;
+        } else {
+            *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+    } else {
+        /* initialize paras for single paragraph */
+        pBiDi->paras=pBiDi->simpleParas;
+        pBiDi->simpleParas[0]=length;
+    }
+
+    /* are explicit levels specified? */
+    if(embeddingLevels==NULL) {
+        /* no: determine explicit levels according to the (Xn) rules */\
+        if(getLevelsMemory(pBiDi, length)) {
+            pBiDi->levels=pBiDi->levelsMemory;
+            direction=resolveExplicitLevels(pBiDi);
+        } else {
+            *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
+    } else {
+        /* set BN for all explicit codes, check that all levels are 0 or paraLevel..UBIDI_MAX_EXPLICIT_LEVEL */
+        pBiDi->levels=embeddingLevels;
+        direction=checkExplicitLevels(pBiDi, pErrorCode);
+        if(U_FAILURE(*pErrorCode)) {
+            return;
+        }
+    }
+
+    /*
+     * The steps after (X9) in the UBiDi algorithm are performed only if
+     * the paragraph text has mixed directionality!
+     */
+    pBiDi->direction=direction;
+    switch(direction) {
+    case UBIDI_LTR:
+        /* make sure paraLevel is even */
+        pBiDi->paraLevel=(UBiDiLevel)((pBiDi->paraLevel+1)&~1);
+
+        /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */
+        pBiDi->trailingWSStart=0;
+        break;
+    case UBIDI_RTL:
+        /* make sure paraLevel is odd */
+        pBiDi->paraLevel|=1;
+
+        /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */
+        pBiDi->trailingWSStart=0;
+        break;
+    default:
+        /*
+         *  Choose the right implicit state table
+         */
+        switch(pBiDi->reorderingMode) {
+        case UBIDI_REORDER_DEFAULT:
+            pBiDi->pImpTabPair=&impTab_DEFAULT;
+            break;
+        case UBIDI_REORDER_NUMBERS_SPECIAL:
+            pBiDi->pImpTabPair=&impTab_NUMBERS_SPECIAL;
+            break;
+        case UBIDI_REORDER_GROUP_NUMBERS_WITH_R:
+            pBiDi->pImpTabPair=&impTab_GROUP_NUMBERS_WITH_R;
+            break;
+        case UBIDI_REORDER_INVERSE_NUMBERS_AS_L:
+            pBiDi->pImpTabPair=&impTab_INVERSE_NUMBERS_AS_L;
+            break;
+        case UBIDI_REORDER_INVERSE_LIKE_DIRECT:
+            if (pBiDi->reorderingOptions & UBIDI_OPTION_INSERT_MARKS) {
+                pBiDi->pImpTabPair=&impTab_INVERSE_LIKE_DIRECT_WITH_MARKS;
+            } else {
+                pBiDi->pImpTabPair=&impTab_INVERSE_LIKE_DIRECT;
+            }
+            break;
+        case UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL:
+            if (pBiDi->reorderingOptions & UBIDI_OPTION_INSERT_MARKS) {
+                pBiDi->pImpTabPair=&impTab_INVERSE_FOR_NUMBERS_SPECIAL_WITH_MARKS;
+            } else {
+                pBiDi->pImpTabPair=&impTab_INVERSE_FOR_NUMBERS_SPECIAL;
+            }
+            break;
+        default:
+            /* we should never get here */
+            U_ASSERT(FALSE);
+            break;
+        }
+        /*
+         * If there are no external levels specified and there
+         * are no significant explicit level codes in the text,
+         * then we can treat the entire paragraph as one run.
+         * Otherwise, we need to perform the following rules on runs of
+         * the text with the same embedding levels. (X10)
+         * "Significant" explicit level codes are ones that actually
+         * affect non-BN characters.
+         * Examples for "insignificant" ones are empty embeddings
+         * LRE-PDF, LRE-RLE-PDF-PDF, etc.
+         */
+        if(embeddingLevels==NULL && pBiDi->paraCount<=1 &&
+                                   !(pBiDi->flags&DIRPROP_FLAG_MULTI_RUNS)) {
+            resolveImplicitLevels(pBiDi, 0, length,
+                                    GET_LR_FROM_LEVEL(GET_PARALEVEL(pBiDi, 0)),
+                                    GET_LR_FROM_LEVEL(GET_PARALEVEL(pBiDi, length-1)));
+        } else {
+            /* sor, eor: start and end types of same-level-run */
+            UBiDiLevel *levels=pBiDi->levels;
+            int32_t start, limit=0;
+            UBiDiLevel level, nextLevel;
+            DirProp sor, eor;
+
+            /* determine the first sor and set eor to it because of the loop body (sor=eor there) */
+            level=GET_PARALEVEL(pBiDi, 0);
+            nextLevel=levels[0];
+            if(level<nextLevel) {
+                eor=GET_LR_FROM_LEVEL(nextLevel);
+            } else {
+                eor=GET_LR_FROM_LEVEL(level);
+            }
+
+            do {
+                /* determine start and limit of the run (end points just behind the run) */
+
+                /* the values for this run's start are the same as for the previous run's end */
+                start=limit;
+                level=nextLevel;
+                if((start>0) && (NO_CONTEXT_RTL(pBiDi->dirProps[start-1])==B)) {
+                    /* except if this is a new paragraph, then set sor = para level */
+                    sor=GET_LR_FROM_LEVEL(GET_PARALEVEL(pBiDi, start));
+                } else {
+                    sor=eor;
+                }
+
+                /* search for the limit of this run */
+                while(++limit<length && levels[limit]==level) {}
+
+                /* get the correct level of the next run */
+                if(limit<length) {
+                    nextLevel=levels[limit];
+                } else {
+                    nextLevel=GET_PARALEVEL(pBiDi, length-1);
+                }
+
+                /* determine eor from max(level, nextLevel); sor is last run's eor */
+                if((level&~UBIDI_LEVEL_OVERRIDE)<(nextLevel&~UBIDI_LEVEL_OVERRIDE)) {
+                    eor=GET_LR_FROM_LEVEL(nextLevel);
+                } else {
+                    eor=GET_LR_FROM_LEVEL(level);
+                }
+
+                /* if the run consists of overridden directional types, then there
+                   are no implicit types to be resolved */
+                if(!(level&UBIDI_LEVEL_OVERRIDE)) {
+                    resolveImplicitLevels(pBiDi, start, limit, sor, eor);
+                } else {
+                    /* remove the UBIDI_LEVEL_OVERRIDE flags */
+                    do {
+                        levels[start++]&=~UBIDI_LEVEL_OVERRIDE;
+                    } while(start<limit);
+                }
+            } while(limit<length);
+        }
+        /* check if we got any memory shortage while adding insert points */
+        if (U_FAILURE(pBiDi->insertPoints.errorCode))
+        {
+            *pErrorCode=pBiDi->insertPoints.errorCode;
+            return;
+        }
+        /* reset the embedding levels for some non-graphic characters (L1), (X9) */
+        adjustWSLevels(pBiDi);
+        break;
+    }
+    /* add RLM for inverse Bidi with contextual orientation resolving
+     * to RTL which would not round-trip otherwise
+     */
+    if((pBiDi->defaultParaLevel>0) &&
+       (pBiDi->reorderingOptions & UBIDI_OPTION_INSERT_MARKS) &&
+       ((pBiDi->reorderingMode==UBIDI_REORDER_INVERSE_LIKE_DIRECT) ||
+        (pBiDi->reorderingMode==UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL))) {
+        int32_t i, j, start, last;
+        DirProp dirProp;
+        for(i=0; i<pBiDi->paraCount; i++) {
+            last=pBiDi->paras[i]-1;
+            if((pBiDi->dirProps[last] & CONTEXT_RTL)==0) {
+                continue;           /* LTR paragraph */
+            }
+            start= i==0 ? 0 : pBiDi->paras[i - 1];
+            for(j=last; j>=start; j--) {
+                dirProp=NO_CONTEXT_RTL(pBiDi->dirProps[j]);
+                if(dirProp==L) {
+                    if(j<last) {
+                        while(NO_CONTEXT_RTL(pBiDi->dirProps[last])==B) {
+                            last--;
+                        }
+                    }
+                    addPoint(pBiDi, last, RLM_BEFORE);
+                    break;
+                }
+                if(DIRPROP_FLAG(dirProp) & MASK_R_AL) {
+                    break;
+                }
+            }
+        }
+    }
+
+    if(pBiDi->reorderingOptions & UBIDI_OPTION_REMOVE_CONTROLS) {
+        pBiDi->resultLength -= pBiDi->controlCount;
+    } else {
+        pBiDi->resultLength += pBiDi->insertPoints.size;
+    }
+    pBiDi->pParaBiDi=pBiDi;             /* mark successful setPara */
+}
+
+U_CAPI void U_EXPORT2
+ubidi_orderParagraphsLTR(UBiDi *pBiDi, UBool orderParagraphsLTR) {
+    if(pBiDi!=NULL) {
+        pBiDi->orderParagraphsLTR=orderParagraphsLTR;
+    }
+}
+
+U_CAPI UBool U_EXPORT2
+ubidi_isOrderParagraphsLTR(UBiDi *pBiDi) {
+    if(pBiDi!=NULL) {
+        return pBiDi->orderParagraphsLTR;
+    } else {
+        return FALSE;
+    }
+}
+
+U_CAPI UBiDiDirection U_EXPORT2
+ubidi_getDirection(const UBiDi *pBiDi) {
+    if(IS_VALID_PARA_OR_LINE(pBiDi)) {
+        return pBiDi->direction;
+    } else {
+        return UBIDI_LTR;
+    }
+}
+
+U_CAPI const UChar * U_EXPORT2
+ubidi_getText(const UBiDi *pBiDi) {
+    if(IS_VALID_PARA_OR_LINE(pBiDi)) {
+        return pBiDi->text;
+    } else {
+        return NULL;
+    }
+}
+
+U_CAPI int32_t U_EXPORT2
+ubidi_getLength(const UBiDi *pBiDi) {
+    if(IS_VALID_PARA_OR_LINE(pBiDi)) {
+        return pBiDi->originalLength;
+    } else {
+        return 0;
+    }
+}
+
+U_CAPI int32_t U_EXPORT2
+ubidi_getProcessedLength(const UBiDi *pBiDi) {
+    if(IS_VALID_PARA_OR_LINE(pBiDi)) {
+        return pBiDi->length;
+    } else {
+        return 0;
+    }
+}
+
+U_CAPI int32_t U_EXPORT2
+ubidi_getResultLength(const UBiDi *pBiDi) {
+    if(IS_VALID_PARA_OR_LINE(pBiDi)) {
+        return pBiDi->resultLength;
+    } else {
+        return 0;
+    }
+}
+
+/* paragraphs API functions ------------------------------------------------- */
+
+U_CAPI UBiDiLevel U_EXPORT2
+ubidi_getParaLevel(const UBiDi *pBiDi) {
+    if(IS_VALID_PARA_OR_LINE(pBiDi)) {
+        return pBiDi->paraLevel;
+    } else {
+        return 0;
+    }
+}
+
+U_CAPI int32_t U_EXPORT2
+ubidi_countParagraphs(UBiDi *pBiDi) {
+    if(!IS_VALID_PARA_OR_LINE(pBiDi)) {
+        return 0;
+    } else {
+        return pBiDi->paraCount;
+    }
+}
+
+U_CAPI void U_EXPORT2
+ubidi_getParagraphByIndex(const UBiDi *pBiDi, int32_t paraIndex,
+                          int32_t *pParaStart, int32_t *pParaLimit,
+                          UBiDiLevel *pParaLevel, UErrorCode *pErrorCode) {
+    int32_t paraStart;
+
+    /* check the argument values */
+    RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrorCode);
+    RETURN_VOID_IF_NOT_VALID_PARA_OR_LINE(pBiDi, *pErrorCode);
+    RETURN_VOID_IF_BAD_RANGE(paraIndex, 0, pBiDi->paraCount, *pErrorCode);
+
+    pBiDi=pBiDi->pParaBiDi;             /* get Para object if Line object */
+    if(paraIndex) {
+        paraStart=pBiDi->paras[paraIndex-1];
+    } else {
+        paraStart=0;
+    }
+    if(pParaStart!=NULL) {
+        *pParaStart=paraStart;
+    }
+    if(pParaLimit!=NULL) {
+        *pParaLimit=pBiDi->paras[paraIndex];
+    }
+    if(pParaLevel!=NULL) {
+        *pParaLevel=GET_PARALEVEL(pBiDi, paraStart);
+    }
+}
+
+U_CAPI int32_t U_EXPORT2
+ubidi_getParagraph(const UBiDi *pBiDi, int32_t charIndex,
+                          int32_t *pParaStart, int32_t *pParaLimit,
+                          UBiDiLevel *pParaLevel, UErrorCode *pErrorCode) {
+    uint32_t paraIndex;
+
+    /* check the argument values */
+    /* pErrorCode will be checked by the call to ubidi_getParagraphByIndex */
+    RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrorCode, -1);
+    RETURN_IF_NOT_VALID_PARA_OR_LINE(pBiDi, *pErrorCode, -1);
+    pBiDi=pBiDi->pParaBiDi;             /* get Para object if Line object */
+    RETURN_IF_BAD_RANGE(charIndex, 0, pBiDi->length, *pErrorCode, -1);
+
+    for(paraIndex=0; charIndex>=pBiDi->paras[paraIndex]; paraIndex++);
+    ubidi_getParagraphByIndex(pBiDi, paraIndex, pParaStart, pParaLimit, pParaLevel, pErrorCode);
+    return paraIndex;
+}
+
+U_CAPI void U_EXPORT2
+ubidi_setClassCallback(UBiDi *pBiDi, UBiDiClassCallback *newFn,
+                       const void *newContext, UBiDiClassCallback **oldFn,
+                       const void **oldContext, UErrorCode *pErrorCode)
+{
+    RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrorCode);
+    if(pBiDi==NULL) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    if( oldFn )
+    {
+        *oldFn = pBiDi->fnClassCallback;
+    }
+    if( oldContext )
+    {
+        *oldContext = pBiDi->coClassCallback;
+    }
+    pBiDi->fnClassCallback = newFn;
+    pBiDi->coClassCallback = newContext;
+}
+
+U_CAPI void U_EXPORT2
+ubidi_getClassCallback(UBiDi *pBiDi, UBiDiClassCallback **fn, const void **context)
+{
+    if(pBiDi==NULL) {
+        return;
+    }
+    if( fn )
+    {
+        *fn = pBiDi->fnClassCallback;
+    }
+    if( context )
+    {
+        *context = pBiDi->coClassCallback;
+    }
+}
+
+U_CAPI UCharDirection U_EXPORT2
+ubidi_getCustomizedClass(UBiDi *pBiDi, UChar32 c)
+{
+    UCharDirection dir;
+
+    if( pBiDi->fnClassCallback == NULL ||
+        (dir = (*pBiDi->fnClassCallback)(pBiDi->coClassCallback, c)) == U_BIDI_CLASS_DEFAULT )
+    {
+        return ubidi_getClass(pBiDi->bdp, c);
+    } else {
+        return dir;
+    }
+}
+
diff --git a/icu/source/common/ubidi_props.c b/icu/source/common/ubidi_props.c
new file mode 100644
index 0000000..b686138
--- /dev/null
+++ b/icu/source/common/ubidi_props.c
@@ -0,0 +1,504 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2004-2008, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  ubidi_props.c
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2004dec30
+*   created by: Markus W. Scherer
+*
+*   Low-level Unicode bidi/shaping properties access.
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/uset.h"
+#include "unicode/udata.h" /* UDataInfo */
+#include "ucmndata.h" /* DataHeader */
+#include "udatamem.h"
+#include "umutex.h"
+#include "uassert.h"
+#include "cmemory.h"
+#include "utrie2.h"
+#include "ubidi_props.h"
+#include "ucln_cmn.h"
+
+struct UBiDiProps {
+    UDataMemory *mem;
+    const int32_t *indexes;
+    const uint32_t *mirrors;
+    const uint8_t *jgArray;
+
+    UTrie2 trie;
+    uint8_t formatVersion[4];
+};
+
+/* data loading etc. -------------------------------------------------------- */
+
+#if UBIDI_HARDCODE_DATA
+
+/* ubidi_props_data.c is machine-generated by genbidi --csource */
+#include "ubidi_props_data.c"
+
+#else
+
+static UBool U_CALLCONV
+isAcceptable(void *context,
+             const char *type, const char *name,
+             const UDataInfo *pInfo) {
+    if(
+        pInfo->size>=20 &&
+        pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
+        pInfo->charsetFamily==U_CHARSET_FAMILY &&
+        pInfo->dataFormat[0]==UBIDI_FMT_0 &&    /* dataFormat="BiDi" */
+        pInfo->dataFormat[1]==UBIDI_FMT_1 &&
+        pInfo->dataFormat[2]==UBIDI_FMT_2 &&
+        pInfo->dataFormat[3]==UBIDI_FMT_3 &&
+        pInfo->formatVersion[0]==1 &&
+        pInfo->formatVersion[2]==UTRIE_SHIFT &&
+        pInfo->formatVersion[3]==UTRIE_INDEX_SHIFT
+    ) {
+        UBiDiProps *bdp=(UBiDiProps *)context;
+        uprv_memcpy(bdp->formatVersion, pInfo->formatVersion, 4);
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+
+static UBiDiProps *
+ubidi_openData(UBiDiProps *bdpProto,
+               const uint8_t *bin, int32_t length, UErrorCode *pErrorCode) {
+    UBiDiProps *bdp;
+    int32_t size;
+
+    bdpProto->indexes=(const int32_t *)bin;
+    if( (length>=0 && length<16*4) ||
+        bdpProto->indexes[UBIDI_IX_INDEX_TOP]<16
+    ) {
+        /* length or indexes[] too short for minimum indexes[] length of 16 */
+        *pErrorCode=U_INVALID_FORMAT_ERROR;
+        return NULL;
+    }
+    size=bdpProto->indexes[UBIDI_IX_INDEX_TOP]*4;
+    if(length>=0) {
+        if(length>=size && length>=bdpProto->indexes[UBIDI_IX_LENGTH]) {
+            length-=size;
+        } else {
+            /* length too short for indexes[] or for the whole data length */
+            *pErrorCode=U_INVALID_FORMAT_ERROR;
+            return NULL;
+        }
+    }
+    bin+=size;
+    /* from here on, assume that the sizes of the items fit into the total length */
+
+    /* unserialize the trie, after indexes[] */
+    size=bdpProto->indexes[UBIDI_IX_TRIE_SIZE];
+    utrie_unserialize(&bdpProto->trie, bin, size, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+    bin+=size;
+
+    /* get mirrors[] */
+    size=4*bdpProto->indexes[UBIDI_IX_MIRROR_LENGTH];
+    bdpProto->mirrors=(const uint32_t *)bin;
+    bin+=size;
+
+    /* get jgArray[] */
+    size=bdpProto->indexes[UBIDI_IX_JG_LIMIT]-bdpProto->indexes[UBIDI_IX_JG_START];
+    bdpProto->jgArray=bin;
+    bin+=size;
+
+    /* allocate, copy, and return the new UBiDiProps */
+    bdp=(UBiDiProps *)uprv_malloc(sizeof(UBiDiProps));
+    if(bdp==NULL) {
+        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
+    } else {
+        uprv_memcpy(bdp, bdpProto, sizeof(UBiDiProps));
+        return bdp;
+    }
+}
+
+U_CFUNC UBiDiProps *
+ubidi_openProps(UErrorCode *pErrorCode) {
+    UBiDiProps bdpProto={ NULL }, *bdp;
+
+    bdpProto.mem=udata_openChoice(NULL, UBIDI_DATA_TYPE, UBIDI_DATA_NAME, isAcceptable, &bdpProto, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+
+    bdp=ubidi_openData(
+            &bdpProto,
+            udata_getMemory(bdpProto.mem),
+            udata_getLength(bdpProto.mem),
+            pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        udata_close(bdpProto.mem);
+        return NULL;
+    } else {
+        return bdp;
+    }
+}
+
+U_CFUNC UBiDiProps *
+ubidi_openBinary(const uint8_t *bin, int32_t length, UErrorCode *pErrorCode) {
+    UBiDiProps bdpProto={ NULL };
+    const DataHeader *hdr;
+
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+    if(bin==NULL) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return NULL;
+    }
+
+    /* check the header */
+    if(length>=0 && length<20) {
+        *pErrorCode=U_INVALID_FORMAT_ERROR;
+        return NULL;
+    }
+    hdr=(const DataHeader *)bin;
+    if(
+        !(hdr->dataHeader.magic1==0xda && hdr->dataHeader.magic2==0x27 &&
+          hdr->info.isBigEndian==U_IS_BIG_ENDIAN &&
+          isAcceptable(&bdpProto, UBIDI_DATA_TYPE, UBIDI_DATA_NAME, &hdr->info))
+    ) {
+        *pErrorCode=U_INVALID_FORMAT_ERROR;
+        return NULL;
+    }
+
+    bin+=hdr->dataHeader.headerSize;
+    if(length>=0) {
+        length-=hdr->dataHeader.headerSize;
+    }
+    return ubidi_openData(&bdpProto, bin, length, pErrorCode);
+}
+
+#endif
+
+U_CFUNC void
+ubidi_closeProps(UBiDiProps *bdp) {
+    if(bdp!=NULL) {
+#if !UBIDI_HARDCODE_DATA
+        udata_close(bdp->mem);
+#endif
+        uprv_free(bdp);
+    }
+}
+
+/* UBiDiProps singleton ----------------------------------------------------- */
+
+#if !UBIDI_HARDCODE_DATA
+static UBiDiProps *gBdpDummy=NULL;
+static UBiDiProps *gBdp=NULL;
+static UErrorCode gErrorCode=U_ZERO_ERROR;
+static int8_t gHaveData=0;
+
+static UBool U_CALLCONV
+ubidi_cleanup(void) {
+    ubidi_closeProps(gBdpDummy);
+    gBdpDummy=NULL;
+    ubidi_closeProps(gBdp);
+    gBdp=NULL;
+    gErrorCode=U_ZERO_ERROR;
+    gHaveData=0;
+    return TRUE;
+}
+#endif
+
+U_CFUNC const UBiDiProps *
+ubidi_getSingleton(UErrorCode *pErrorCode) {
+#if UBIDI_HARDCODE_DATA
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+    return &ubidi_props_singleton;
+#else
+    int8_t haveData;
+
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+
+    UMTX_CHECK(NULL, gHaveData, haveData);
+
+    if(haveData>0) {
+        /* data was loaded */
+        return gBdp;
+    } else if(haveData<0) {
+        /* data loading failed */
+        *pErrorCode=gErrorCode;
+        return NULL;
+    } else /* haveData==0 */ {
+        /* load the data */
+        UBiDiProps *bdp=ubidi_openProps(pErrorCode);
+        if(U_FAILURE(*pErrorCode)) {
+            gHaveData=-1;
+            gErrorCode=*pErrorCode;
+            return NULL;
+        }
+
+        /* set the static variables */
+        umtx_lock(NULL);
+        if(gBdp==NULL) {
+            gBdp=bdp;
+            bdp=NULL;
+            gHaveData=1;
+            ucln_common_registerCleanup(UCLN_COMMON_UBIDI, ubidi_cleanup);
+        }
+        umtx_unlock(NULL);
+
+        ubidi_closeProps(bdp);
+        return gBdp;
+    }
+#endif
+}
+
+#if !UBIDI_HARDCODE_DATA
+U_CAPI const UBiDiProps *
+ubidi_getDummy(UErrorCode *pErrorCode) {
+    UBiDiProps *bdp;
+
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+
+    UMTX_CHECK(NULL, gBdpDummy, bdp);
+
+    if(bdp!=NULL) {
+        /* the dummy object was already created */
+        return bdp;
+    } else /* bdp==NULL */ {
+        /* create the dummy object */
+        int32_t *indexes;
+        
+        bdp=(UBiDiProps *)uprv_malloc(sizeof(UBiDiProps)+UBIDI_IX_TOP*4+UTRIE_DUMMY_SIZE);
+        if(bdp==NULL) {
+            *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+            return NULL;
+        }
+        uprv_memset(bdp, 0, sizeof(UBiDiProps)+UBIDI_IX_TOP*4);
+
+        bdp->indexes=indexes=(int32_t *)(bdp+1);
+        indexes[UBIDI_IX_INDEX_TOP]=UBIDI_IX_TOP;
+
+        indexes[UBIDI_IX_TRIE_SIZE]=
+            utrie_unserializeDummy(&bdp->trie, indexes+UBIDI_IX_TOP, UTRIE_DUMMY_SIZE, 0, 0, TRUE, pErrorCode);
+        if(U_FAILURE(*pErrorCode)) {
+            uprv_free(bdp);
+            return NULL;
+        }
+
+        bdp->formatVersion[0]=1;
+        bdp->formatVersion[2]=UTRIE_SHIFT;
+        bdp->formatVersion[3]=UTRIE_INDEX_SHIFT;
+
+        /* set the static variables */
+        umtx_lock(NULL);
+        if(gBdpDummy==NULL) {
+            gBdpDummy=bdp;
+            bdp=NULL;
+            ucln_common_registerCleanup(UCLN_COMMON_UBIDI, ubidi_cleanup);
+        }
+        umtx_unlock(NULL);
+
+        uprv_free(bdp);
+        return gBdpDummy;
+    }
+}
+#endif
+
+/* set of property starts for UnicodeSet ------------------------------------ */
+
+static UBool U_CALLCONV
+_enumPropertyStartsRange(const void *context, UChar32 start, UChar32 end, uint32_t value) {
+    /* add the start code point to the USet */
+    const USetAdder *sa=(const USetAdder *)context;
+    sa->add(sa->set, start);
+    return TRUE;
+}
+
+U_CFUNC void
+ubidi_addPropertyStarts(const UBiDiProps *bdp, const USetAdder *sa, UErrorCode *pErrorCode) {
+    int32_t i, length;
+    UChar32 c, start, limit;
+
+    const uint8_t *jgArray;
+    uint8_t prev, jg;
+
+    if(U_FAILURE(*pErrorCode)) {
+        return;
+    }
+
+    /* add the start code point of each same-value range of the trie */
+    utrie2_enum(&bdp->trie, NULL, _enumPropertyStartsRange, sa);
+
+    /* add the code points from the bidi mirroring table */
+    length=bdp->indexes[UBIDI_IX_MIRROR_LENGTH];
+    for(i=0; i<length; ++i) {
+        c=UBIDI_GET_MIRROR_CODE_POINT(bdp->mirrors[i]);
+        sa->addRange(sa->set, c, c+1);
+    }
+
+    /* add the code points from the Joining_Group array where the value changes */
+    start=bdp->indexes[UBIDI_IX_JG_START];
+    limit=bdp->indexes[UBIDI_IX_JG_LIMIT];
+    jgArray=bdp->jgArray;
+    prev=0;
+    while(start<limit) {
+        jg=*jgArray++;
+        if(jg!=prev) {
+            sa->add(sa->set, start);
+            prev=jg;
+        }
+        ++start;
+    }
+    if(prev!=0) {
+        /* add the limit code point if the last value was not 0 (it is now start==limit) */
+        sa->add(sa->set, limit);
+    }
+
+    /* add code points with hardcoded properties, plus the ones following them */
+
+    /* (none right now) */
+}
+
+/* property access functions ------------------------------------------------ */
+
+U_CFUNC int32_t
+ubidi_getMaxValue(const UBiDiProps *bdp, UProperty which) {
+    int32_t max;
+
+    if(bdp==NULL) {
+        return -1;
+    }
+
+    max=bdp->indexes[UBIDI_MAX_VALUES_INDEX];
+    switch(which) {
+    case UCHAR_BIDI_CLASS:
+        return (max&UBIDI_CLASS_MASK);
+    case UCHAR_JOINING_GROUP:
+        return (max&UBIDI_MAX_JG_MASK)>>UBIDI_MAX_JG_SHIFT;
+    case UCHAR_JOINING_TYPE:
+        return (max&UBIDI_JT_MASK)>>UBIDI_JT_SHIFT;
+    default:
+        return -1; /* undefined */
+    }
+}
+
+U_CAPI UCharDirection
+ubidi_getClass(const UBiDiProps *bdp, UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
+    return (UCharDirection)UBIDI_GET_CLASS(props);
+}
+
+U_CFUNC UBool
+ubidi_isMirrored(const UBiDiProps *bdp, UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
+    return (UBool)UBIDI_GET_FLAG(props, UBIDI_IS_MIRRORED_SHIFT);
+}
+
+U_CFUNC UChar32
+ubidi_getMirror(const UBiDiProps *bdp, UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
+    int32_t delta=((int16_t)props)>>UBIDI_MIRROR_DELTA_SHIFT;
+    if(delta!=UBIDI_ESC_MIRROR_DELTA) {
+        return c+delta;
+    } else {
+        /* look for mirror code point in the mirrors[] table */
+        const uint32_t *mirrors;
+        uint32_t m;
+        int32_t i, length;
+        UChar32 c2;
+
+        mirrors=bdp->mirrors;
+        length=bdp->indexes[UBIDI_IX_MIRROR_LENGTH];
+
+        /* linear search */
+        for(i=0; i<length; ++i) {
+            m=mirrors[i];
+            c2=UBIDI_GET_MIRROR_CODE_POINT(m);
+            if(c==c2) {
+                /* found c, return its mirror code point using the index in m */
+                return UBIDI_GET_MIRROR_CODE_POINT(mirrors[UBIDI_GET_MIRROR_INDEX(m)]);
+            } else if(c<c2) {
+                break;
+            }
+        }
+
+        /* c not found, return it itself */
+        return c;
+    }
+}
+
+U_CFUNC UBool
+ubidi_isBidiControl(const UBiDiProps *bdp, UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
+    return (UBool)UBIDI_GET_FLAG(props, UBIDI_BIDI_CONTROL_SHIFT);
+}
+
+U_CFUNC UBool
+ubidi_isJoinControl(const UBiDiProps *bdp, UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
+    return (UBool)UBIDI_GET_FLAG(props, UBIDI_JOIN_CONTROL_SHIFT);
+}
+
+U_CFUNC UJoiningType
+ubidi_getJoiningType(const UBiDiProps *bdp, UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&bdp->trie, c);
+    return (UJoiningType)((props&UBIDI_JT_MASK)>>UBIDI_JT_SHIFT);
+}
+
+U_CFUNC UJoiningGroup
+ubidi_getJoiningGroup(const UBiDiProps *bdp, UChar32 c) {
+    UChar32 start, limit;
+
+    start=bdp->indexes[UBIDI_IX_JG_START];
+    limit=bdp->indexes[UBIDI_IX_JG_LIMIT];
+    if(start<=c && c<limit) {
+        return (UJoiningGroup)bdp->jgArray[c-start];
+    } else {
+        return U_JG_NO_JOINING_GROUP;
+    }
+}
+
+/* public API (see uchar.h) ------------------------------------------------- */
+
+U_CFUNC UCharDirection
+u_charDirection(UChar32 c) {   
+    UErrorCode errorCode=U_ZERO_ERROR;
+    const UBiDiProps *bdp=ubidi_getSingleton(&errorCode);
+    if(bdp!=NULL) {
+        return ubidi_getClass(bdp, c);
+    } else {
+        return U_LEFT_TO_RIGHT;
+    }
+}
+
+U_CFUNC UBool
+u_isMirrored(UChar32 c) {
+    UErrorCode errorCode=U_ZERO_ERROR;
+    const UBiDiProps *bdp=ubidi_getSingleton(&errorCode);
+    return (UBool)(bdp!=NULL && ubidi_isMirrored(bdp, c));
+}
+
+U_CFUNC UChar32
+u_charMirror(UChar32 c) {
+    UErrorCode errorCode=U_ZERO_ERROR;
+    const UBiDiProps *bdp=ubidi_getSingleton(&errorCode);
+    if(bdp!=NULL) {
+        return ubidi_getMirror(bdp, c);
+    } else {
+        return c;
+    }
+}
diff --git a/icu/source/common/ubidi_props.h b/icu/source/common/ubidi_props.h
new file mode 100644
index 0000000..c2384c7
--- /dev/null
+++ b/icu/source/common/ubidi_props.h
@@ -0,0 +1,163 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2004-2008, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  ubidi_props.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2004dec30
+*   created by: Markus W. Scherer
+*
+*   Low-level Unicode bidi/shaping properties access.
+*/
+
+#ifndef __UBIDI_PROPS_H__
+#define __UBIDI_PROPS_H__
+
+#include "unicode/utypes.h"
+#include "unicode/uset.h"
+#include "uset_imp.h"
+#include "udataswp.h"
+
+#define UBIDI_HARDCODE_DATA 1
+
+U_CDECL_BEGIN
+
+/* library API -------------------------------------------------------------- */
+
+struct UBiDiProps;
+typedef struct UBiDiProps UBiDiProps;
+
+U_CFUNC UBiDiProps *
+ubidi_openProps(UErrorCode *pErrorCode);
+
+U_CFUNC UBiDiProps *
+ubidi_openBinary(const uint8_t *bin, int32_t length, UErrorCode *pErrorCode);
+
+U_CFUNC void
+ubidi_closeProps(UBiDiProps *bdp);
+
+
+U_CFUNC const UBiDiProps *
+ubidi_getSingleton(UErrorCode *pErrorCode);
+
+#if !UBIDI_HARDCODE_DATA
+/**
+ * Get a singleton dummy object, one that works with no real data.
+ * This can be used when the real data is not available.
+ * Using the dummy can reduce checks for available data after an initial failure.
+ */
+U_CAPI const UBiDiProps *
+ubidi_getDummy(UErrorCode *pErrorCode);
+#endif
+
+U_CAPI int32_t
+ubidi_swap(const UDataSwapper *ds,
+           const void *inData, int32_t length, void *outData,
+           UErrorCode *pErrorCode);
+
+U_CFUNC void
+ubidi_addPropertyStarts(const UBiDiProps *bdp, const USetAdder *sa, UErrorCode *pErrorCode);
+
+/* property access functions */
+
+U_CFUNC int32_t
+ubidi_getMaxValue(const UBiDiProps *bdp, UProperty which);
+
+U_CAPI UCharDirection
+ubidi_getClass(const UBiDiProps *bdp, UChar32 c);
+
+U_CFUNC UBool
+ubidi_isMirrored(const UBiDiProps *bdp, UChar32 c);
+
+U_CFUNC UChar32
+ubidi_getMirror(const UBiDiProps *bdp, UChar32 c);
+
+U_CFUNC UBool
+ubidi_isBidiControl(const UBiDiProps *bdp, UChar32 c);
+
+U_CFUNC UBool
+ubidi_isJoinControl(const UBiDiProps *bdp, UChar32 c);
+
+U_CFUNC UJoiningType
+ubidi_getJoiningType(const UBiDiProps *bdp, UChar32 c);
+
+U_CFUNC UJoiningGroup
+ubidi_getJoiningGroup(const UBiDiProps *bdp, UChar32 c);
+
+/* file definitions --------------------------------------------------------- */
+
+#define UBIDI_DATA_NAME "ubidi"
+#define UBIDI_DATA_TYPE "icu"
+
+/* format "BiDi" */
+#define UBIDI_FMT_0 0x42
+#define UBIDI_FMT_1 0x69
+#define UBIDI_FMT_2 0x44
+#define UBIDI_FMT_3 0x69
+
+/* indexes into indexes[] */
+enum {
+    UBIDI_IX_INDEX_TOP,
+    UBIDI_IX_LENGTH,
+    UBIDI_IX_TRIE_SIZE,
+    UBIDI_IX_MIRROR_LENGTH,
+
+    UBIDI_IX_JG_START,
+    UBIDI_IX_JG_LIMIT,
+
+    UBIDI_MAX_VALUES_INDEX=15,
+    UBIDI_IX_TOP=16
+};
+
+/* definitions for 16-bit bidi/shaping properties word ---------------------- */
+
+enum {
+ /* UBIDI_CLASS_SHIFT=0, */     /* bidi class: 5 bits (4..0) */
+    UBIDI_JT_SHIFT=5,           /* joining type: 3 bits (7..5) */
+
+    /* UBIDI__SHIFT=8, reserved: 2 bits (9..8) */
+
+    UBIDI_JOIN_CONTROL_SHIFT=10,
+    UBIDI_BIDI_CONTROL_SHIFT=11,
+
+    UBIDI_IS_MIRRORED_SHIFT=12,         /* 'is mirrored' */
+    UBIDI_MIRROR_DELTA_SHIFT=13,        /* bidi mirroring delta: 3 bits (15..13) */
+
+    UBIDI_MAX_JG_SHIFT=16               /* max JG value in indexes[UBIDI_MAX_VALUES_INDEX] bits 23..16 */
+};
+
+#define UBIDI_CLASS_MASK        0x0000001f
+#define UBIDI_JT_MASK           0x000000e0
+
+#define UBIDI_MAX_JG_MASK       0x00ff0000
+
+#define UBIDI_GET_CLASS(props) ((props)&UBIDI_CLASS_MASK)
+#define UBIDI_GET_FLAG(props, shift) (((props)>>(shift))&1)
+
+enum {
+    UBIDI_ESC_MIRROR_DELTA=-4,
+    UBIDI_MIN_MIRROR_DELTA=-3,
+    UBIDI_MAX_MIRROR_DELTA=3
+};
+
+/* definitions for 32-bit mirror table entry -------------------------------- */
+
+enum {
+    /* the source Unicode code point takes 21 bits (20..0) */
+    UBIDI_MIRROR_INDEX_SHIFT=21,
+    UBIDI_MAX_MIRROR_INDEX=0x7ff
+};
+
+#define UBIDI_GET_MIRROR_CODE_POINT(m) (UChar32)((m)&0x1fffff)
+
+#define UBIDI_GET_MIRROR_INDEX(m) ((m)>>UBIDI_MIRROR_INDEX_SHIFT)
+
+U_CDECL_END
+
+#endif
diff --git a/icu/source/common/ubidi_props_data.c b/icu/source/common/ubidi_props_data.c
new file mode 100644
index 0000000..8f584d6
--- /dev/null
+++ b/icu/source/common/ubidi_props_data.c
@@ -0,0 +1,669 @@
+/*
+ * Copyright (C) 1999-2009, International Business Machines
+ * Corporation and others.  All Rights Reserved.
+ *
+ * file name: ubidi_props_data.c
+ *
+ * machine-generated on: 2009-10-24
+ */
+
+static const UVersionInfo ubidi_props_dataVersion={5,2,0,0};
+
+static const int32_t ubidi_props_indexes[UBIDI_IX_TOP]={0x10,0x47c0,0x45b8,0x1a,0x622,0x782,0,0,0,0,0,0,0,0,0,0x3800b2};
+
+static const uint16_t ubidi_props_trieIndex[9632]={
+0x304,0x30c,0x314,0x31c,0x334,0x33c,0x344,0x34c,0x324,0x32c,0x324,0x32c,0x324,0x32c,0x324,0x32c,
+0x324,0x32c,0x324,0x32c,0x352,0x35a,0x362,0x36a,0x372,0x37a,0x376,0x37e,0x386,0x38e,0x389,0x391,
+0x324,0x32c,0x324,0x32c,0x399,0x3a1,0x324,0x32c,0x324,0x32c,0x324,0x32c,0x3a7,0x3af,0x3b7,0x3bf,
+0x3c7,0x3cf,0x3d7,0x3df,0x3e5,0x3ed,0x3f5,0x3fd,0x405,0x40d,0x413,0x41b,0x423,0x42b,0x433,0x43b,
+0x442,0x449,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x451,0x452,0x45a,0x462,0x46a,0x452,0x472,0x47a,
+0x482,0x452,0x48a,0x48f,0x482,0x452,0x497,0x49f,0x46a,0x4a4,0x4ac,0x462,0x4b1,0x324,0x4b9,0x4bd,
+0x324,0x4c4,0x4cc,0x4d4,0x324,0x4dc,0x4e4,0x4ec,0x324,0x324,0x472,0x462,0x324,0x324,0x4f2,0x324,
+0x324,0x4f8,0x500,0x324,0x324,0x504,0x50c,0x324,0x510,0x517,0x324,0x51f,0x527,0x52e,0x4b0,0x324,
+0x324,0x536,0x53e,0x546,0x54e,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x556,0x324,0x55e,0x324,0x324,0x324,
+0x566,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x56e,0x324,0x324,0x324,0x576,0x576,0x476,0x476,0x324,0x57c,0x584,0x55e,
+0x58c,0x324,0x324,0x324,0x324,0x468,0x324,0x324,0x324,0x594,0x59c,0x324,0x324,0x324,0x59e,0x5a6,
+0x5ae,0x324,0x5b5,0x5bd,0x324,0x324,0x324,0x324,0x5c5,0x5c8,0x4b1,0x5d0,0x39b,0x5d8,0x324,0x324,
+0x324,0x5dd,0x324,0x324,0x324,0x324,0x5e3,0x5eb,0x324,0x324,0x324,0x324,0x324,0x324,0x372,0x5f3,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x5fb,0x603,0x607,
+0x60f,0x615,0x61c,0x624,0x62c,0x634,0x63b,0x531,0x643,0x64b,0x653,0x324,0x65b,0x5a6,0x5a6,0x5a6,
+0x663,0x66b,0x673,0x67b,0x680,0x688,0x690,0x696,0x69e,0x6a6,0x324,0x6ac,0x6b3,0x5a6,0x5a6,0x6b9,
+0x5a6,0x4da,0x6c1,0x5a6,0x6c9,0x324,0x324,0x5a3,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,
+0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x6d1,0x6d6,0x6de,0x6e6,0x6ec,0x6f1,0x6f9,0x6ff,0x705,0x70d,0x715,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x5a6,0x5a6,0x5a6,0x5a6,0x71d,0x724,0x72c,0x734,
+0x73c,0x744,0x74c,0x753,0x75b,0x763,0x76a,0x772,0x5a6,0x5a6,0x77a,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x781,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x372,
+0x789,0x791,0x324,0x324,0x799,0x5a6,0x5a6,0x5a9,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x5a6,0x7a0,0x7a6,
+0x7ae,0x7b6,0x324,0x324,0x7be,0x566,0x324,0x34b,0x324,0x324,0x324,0x324,0x324,0x324,0x5a6,0x7c6,
+0x359,0x324,0x7ca,0x7d2,0x324,0x7da,0x7e2,0x324,0x324,0x324,0x324,0x7e6,0x324,0x324,0x59e,0x34a,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x5a6,0x5a6,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x7ca,0x5a6,0x4da,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x7ed,0x324,0x324,0x7f2,0x324,0x324,0x324,0x512,0x5a6,0x59d,0x324,0x324,0x7fa,0x324,0x324,0x324,
+0x802,0x809,0x324,0x810,0x324,0x324,0x817,0x81f,0x324,0x826,0x82d,0x324,0x451,0x832,0x324,0x324,
+0x324,0x83a,0x842,0x324,0x324,0x846,0x46a,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x84e,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x852,0x85a,0x85e,0x423,0x423,0x423,0x423,0x423,
+0x423,0x423,0x423,0x423,0x423,0x423,0x423,0x423,0x423,0x862,0x423,0x423,0x423,0x423,0x86a,0x86e,
+0x876,0x87e,0x882,0x88a,0x423,0x423,0x423,0x88e,0x896,0x314,0x89e,0x8a6,0x324,0x324,0x324,0x8ae,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0xc90,0xc90,0xcd0,0xd10,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xd48,0xd88,0xdc8,0xdd8,0xe18,0xe24,
+0xc90,0xc90,0xe64,0xc90,0xc90,0xc90,0xe9c,0xedc,0xf1c,0xf5c,0xf94,0xfd4,0x1014,0x104c,0x108c,0x10cc,
+0xa40,0xa80,0xac0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xaf5,0x1a0,0x1a0,0xb35,0xb75,0xb7e,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb7e,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb7e,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb7e,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb7e,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb7e,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb7e,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb7e,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb7e,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb7e,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb7e,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb7e,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb7e,
+0xbbe,0xbce,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb7e,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb7e,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,
+0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0x1a0,0xb7e,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x8b6,0x324,0x5a6,0x5a6,0x8be,0x324,0x324,0x463,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x8c6,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,
+0x8ce,0x8d2,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x8da,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,
+0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,
+0x3b9,0x3b9,0x3b9,0x8e2,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,
+0x324,0x324,0x324,0x324,0x39b,0x8ea,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x8f2,0x8fa,0x900,0x324,0x324,0x5a6,0x5a6,0x908,0x324,0x324,0x324,0x324,0x324,0x5a6,0x5a6,0x910,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x916,0x324,0x91d,0x324,0x919,
+0x324,0x920,0x324,0x928,0x92c,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,
+0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,
+0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,
+0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,
+0x3b9,0x3b9,0x3b9,0x3b9,0x3b9,0x5a6,0x934,0x5a6,0x5a6,0x5a9,0x324,0x324,0x324,0x93c,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,
+0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x324,0x93f,0x947,0x94f,
+0x94f,0x94f,0x957,0x957,0x957,0x957,0x372,0x372,0x372,0x372,0x372,0x372,0x372,0x95f,0x957,0x957,
+0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,
+0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,
+0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,
+0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x957,0x303,0x303,
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,8,7,8,9,7,0x12,0x12,
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,7,7,7,8,
+9,0xa,0xa,4,4,4,0xa,0xa,0x300a,0xf00a,0xa,3,6,3,6,6,
+2,2,2,2,2,2,2,2,2,2,6,0xa,0x500a,0xa,0xd00a,0xa,
+0xa,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0x500a,0xa,0xd00a,0xa,0xa,
+0xa,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0x500a,0xa,0xd00a,0xa,0x12,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x12,0x12,0x12,0x12,0x12,7,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+6,0xa,4,4,4,4,0xa,0xa,0xa,0xa,0,0x900a,0xa,0xb2,0xa,0xa,
+4,4,2,2,0xa,0,0xa,0xa,0xa,2,0,0x900a,0xa,0xa,0xa,0xa,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0xa,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0xa,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0xa,0xa,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0xa,0xa,0,0,
+0,0,0,0,0,0,0xa,0,0,0,0,0,0xa,0xa,0,0xa,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0xa,0,0,0,0,0,
+0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0xa,0,0,0,0,0,1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,1,0xb1,1,0xb1,0xb1,1,
+0xb1,0xb1,1,0xb1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,5,5,5,5,
+0xd,0xd,0xa,0xa,0xd,4,4,0xd,6,0xd,0xa,0xa,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0x8d,0x8d,
+0x8d,0x8d,0x4d,0x8d,0x4d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x8d,0x8d,0x8d,0x8d,0x4d,
+0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x2d,0x4d,0x4d,0x4d,
+0x4d,0x4d,0x4d,0x4d,0x8d,0x4d,0x4d,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xd,5,5,5,5,
+5,5,5,5,5,5,4,5,5,0xd,0x4d,0x4d,0xb1,0x8d,0x8d,0x8d,
+0xd,0x8d,0x8d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x8d,0x8d,0x8d,0x8d,
+0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x4d,0x4d,
+0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
+0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
+0x4d,0x4d,0x4d,0x4d,0x8d,0x4d,0x4d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,0x8d,
+0x4d,0x8d,0x4d,0x8d,0x4d,0x4d,0x8d,0x8d,0xd,0x8d,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,5,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xd,0xd,0xb1,0xb1,0xa,0xb1,0xb1,
+0xb1,0xb1,0x8d,0x8d,2,2,2,2,2,2,2,2,2,2,0x4d,0x4d,
+0x4d,0xd,0xd,0x4d,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xb2,0x8d,0xb1,0x4d,0x4d,0x4d,0x8d,0x8d,0x8d,0x8d,0x8d,0x4d,0x4d,
+0x4d,0x4d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x8d,0x4d,0x8d,0x4d,
+0x8d,0x4d,0x4d,0x8d,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xd,0xd,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
+0x4d,0x4d,0x4d,0x4d,0x4d,0x8d,0x8d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,
+0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0x8d,0x8d,0x4d,0x4d,0x4d,0x4d,0x8d,0x4d,0x8d,
+0x8d,0x4d,0x4d,0x4d,0x8d,0x8d,0x4d,0x4d,0x4d,0x4d,0x4d,0x4d,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,1,1,1,1,
+1,1,1,1,1,1,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
+0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
+0x41,0x41,0x41,0x41,0x41,0x41,0x41,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+1,1,0xa,0xa,0xa,0xa,0x21,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,0xb1,0xb1,
+0xb1,0xb1,1,0xb1,0xb1,0xb1,0xb1,0xb1,1,0xb1,0xb1,0xb1,1,0xb1,0xb1,0xb1,
+0xb1,0xb1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xb1,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0,0,0,0,0xb1,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,
+0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0xb1,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0,0,0,
+0,0,0,0,0,0xb1,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,
+0,0,0,4,0,0,0,0,0,0xb1,0xb1,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0xb1,0xb1,0,0,0,0,0xb1,
+0xb1,0,0,0xb1,0xb1,0xb1,0,0,0,0xb1,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0,0,
+0,0xb1,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,
+0xb1,0xb1,0,0xb1,0xb1,0,0,0,0,0xb1,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,
+0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0,0,0xb1,
+0,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0xb1,0,0,
+0,0,0,0,0,0,0xb1,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xb1,0,0,0,0,0,0,0,0,0,0,0,
+0,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,4,0xa,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,
+0xb1,0,0,0,0,0,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,0,0,
+0,0,0,0,0,0xb1,0xb1,0,0,0,0,0,0,0,0,0,
+0,0,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0,0,0xa0,
+0,0,0,0,0,0,0xa0,0,0,0,0,0,0xb1,0xb1,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0xb1,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0,0xb1,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0xb1,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,4,
+0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0xb1,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0,0,0,
+0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0xb1,0xb1,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0xb1,0,0xb1,0,0xb1,0x300a,0xf00a,0x300a,0xf00a,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,
+0xb1,0,0xb1,0xb1,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0,0xb1,0xb1,0,0,0xb1,0xb1,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xb1,0xb1,0,0,0,0,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0xb1,0,0,0xb1,0xb1,0,
+0,0,0,0,0,0xb1,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0xb1,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0xb1,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0,0,0,0,0,0,0xa,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0x300a,0xf00a,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xa0,0xa0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,
+0,0,0,0,0,0,0xb1,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,4,0,0xb1,0,0,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xb1,0xb1,0xb1,9,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xb1,0xb1,0xb1,0,0,0,0,0xb1,0xb1,0,0,0,0,0,0,0,
+0,0,0xb1,0,0,0,0,0,0,0xb1,0xb1,0xb1,0,0,0,0,
+0xa,0,0,0,0xa,0xa,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,
+0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0xb1,0,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0,0xb1,0,0xb1,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xb1,0,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0xb1,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0xa,0,0xa,0xa,0xa,0,0,
+0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0xa,0xa,0,9,9,9,9,
+9,9,9,9,9,9,9,0xb2,0x412,0x432,0x8a0,0x8a1,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,9,7,0x8ab,0x8ae,
+0x8b0,0x8ac,0x8af,6,4,4,4,4,4,0xa,0xa,0xa,0xa,0x300a,0xf00a,0xa,
+0xa,0xa,0xa,0xa,6,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,9,
+0xb2,0xb2,0xb2,0xb2,0xb2,0x12,0x12,0x12,0x12,0x12,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,
+2,0,0,0,2,2,2,2,2,2,3,3,0xa,0x300a,0xf00a,0,
+2,2,2,2,2,2,2,2,2,2,3,3,0xa,0x300a,0xf00a,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xa,0xa,0,0xa,
+0xa,0xa,0xa,0,0xa,0xa,0,0,0,0,0,0,0,0,0,0,
+0xa,0,0xa,0xa,0xa,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,
+0,0xa,0,0xa,0,0xa,0,0,0,0,4,0,0,0,0,0,
+0,0,0,0,0,0,0xa,0xa,0,0,0,0,0x100a,0xa,0xa,0xa,
+0xa,0,0,0,0,0,0xa,0xa,0xa,0xa,0,0,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,
+0,0,0,0,0,0xa,0,0,0,0,0,0,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x100a,0x100a,0x100a,
+0x100a,0xa,0xa,0xa,0x700a,0x700a,0x700a,0xb00a,0xb00a,0xb00a,0xa,0xa,0xa,0x100a,3,4,
+0xa,0x900a,0x100a,0xa,0xa,0xa,0x100a,0x100a,0x100a,0x100a,0xa,0x100a,0x100a,0x100a,0x100a,0xa,
+0x100a,0xa,0x100a,0xa,0xa,0xa,0xa,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,
+0xa,0xa,0xa,0xa,0xa,0x100a,0xa,0x100a,0x300a,0xf00a,0x100a,0x100a,0x100a,0x100a,0x100a,0x900a,
+0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,
+0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x100a,0x100a,0xa,0x100a,0xa,
+0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,
+0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x100a,0xa,0xa,0x300a,
+0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0x900a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0x300a,0xf00a,0xa,0xa,0x900a,0x100a,0x900a,0x900a,0x100a,0x900a,0x100a,0x100a,0x100a,0x100a,
+0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x100a,0xa,0xa,0xa,0xa,0xa,0x100a,0x100a,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x900a,0xa,0xa,
+0x300a,0xf00a,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,
+0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0x300a,0xf00a,0x900a,0x900a,0x900a,0x100a,0x900a,0x900a,
+0x100a,0x100a,0x900a,0x900a,0x900a,0x900a,0x900a,0x100a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x100a,0x100a,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0xa,0,0,0,0,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0xa,0xa,0xa,0xa,0,0xa,0xa,
+0xa,0xa,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0,0xa,0,0xa,0xa,0xa,0xa,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,
+0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0,0x100a,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0xa,0x300a,0xf00a,0xa,0,
+0x100a,0,0,0,0xa,0xa,0xa,0x100a,0x100a,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,
+0x100a,0x300a,0xf00a,0xa,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,
+0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,
+0xf00a,0x700a,0x300a,0xf00a,0xb00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0x100a,
+0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x900a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0x300a,0xf00a,0x100a,0x100a,0x300a,0xf00a,0xa,0xa,0xa,0x100a,0xa,0xa,0xa,0xa,0x100a,0x300a,
+0xf00a,0x300a,0xf00a,0xa,0x300a,0xf00a,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x100a,0xa,0xa,0xa,
+0xa,0x100a,0xa,0x100a,0x100a,0x100a,0xa,0xa,0x100a,0x100a,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0x100a,0x900a,0x100a,0x100a,0x300a,0xf00a,0xa,0xa,0x300a,0xf00a,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,
+0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0xa,0x100a,0x100a,
+0x100a,0x100a,0xa,0xa,0x100a,0xa,0x100a,0xa,0xa,0x100a,0xa,0x300a,0xf00a,0x300a,0xf00a,0xa,
+0xa,0xa,0xa,0xa,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x100a,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0x100a,0x100a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0x300a,0xf00a,0xa,0xa,0xa,0xa,0x100a,0x100a,0x100a,0x100a,0xa,0x100a,0x100a,0xa,0xa,0x100a,
+0x100a,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x100a,0x100a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,
+0xf00a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x300a,0xf00a,0x100a,0x100a,0x100a,0x100a,0x300a,0xf00a,0x300a,
+0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x100a,0x100a,0x100a,0x100a,0x300a,0xf00a,0x100a,
+0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0x300a,0xf00a,0x100a,0x100a,0x300a,
+0xf00a,0x100a,0x100a,0x100a,0x100a,0x100a,0x100a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x100a,
+0x100a,0x100a,0x100a,0x100a,0x100a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,
+0xa,0xa,0xa,0xa,0x100a,0xa,0x900a,0xa,0xa,0xa,0x100a,0x900a,0x900a,0x900a,0x100a,0xa,
+0xa,0xa,0xa,0xa,0x300a,0xf00a,0x100a,0xa,0xa,0xa,0xa,0x100a,0xa,0xa,0xa,0x300a,
+0xf00a,0x300a,0xf00a,0x100a,0xa,0x100a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0,
+0,0,0,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0x300a,0xf00a,0xa,
+0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0x300a,0xf00a,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0,0,0,0,9,0xa,0xa,0xa,0xa,0,0,0,
+0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0x300a,0xf00a,0x300a,0xf00a,
+0x300a,0xf00a,0x300a,0xf00a,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,
+0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xa,0,0,0,0,0,0xa,0xa,
+0,0,0,0,0,0xa,0xa,0xa,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0xb1,0xb1,0xa,0xa,0,0,0,0xa,0xa,0xa,0xa,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,
+0,0,0,0,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xa,
+0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xa,0,0,0,0,
+0,0,0,0,0xb1,0xb1,0xa,0xa,0,0,0,0,0,0,0,0,
+0xa,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0xb1,0,0,0,0xb1,0,
+0,0,0,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0xb1,0xb1,0,0xa,0xa,0xa,0xa,
+0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,
+0xb1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0xb1,0,0,0xb1,0xb1,
+0xb1,0xb1,0,0,0xb1,0,0,0,0,0,0,0,0,0,0,0,
+0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,0,0,0xb1,0xb1,0,
+0,0,0,0,0,0,0,0,0,0,0,0xb1,0,0,0,0,
+0,0,0,0,0xb1,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0xb1,0,0xb1,0xb1,0xb1,0,0,0xb1,
+0xb1,0,0,0,0,0,0xb1,0xb1,0,0,0,0,0,0xb1,0,0,
+0xb1,0,0,0,0,0xb1,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,1,0xb1,1,1,1,1,1,1,1,1,1,
+1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0xd,0xd,0xa,0xa,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0xd,0xa,0xd,0xd,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,
+0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,6,0xa,6,0,0xa,6,0xa,0xa,
+0xa,0x300a,0xf00a,0x300a,0xf00a,0x300a,0xf00a,4,0xa,0xa,3,3,0x300a,0xf00a,0xa,0,
+0xa,4,4,0xa,0,0,0,0,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xd,
+0xd,0xd,0xd,0xd,0xd,0xd,0xd,0xb2,0,0xa,0xa,4,4,4,0xa,0xa,
+0x300a,0xf00a,0xa,3,6,3,6,6,2,2,2,2,2,2,2,2,
+2,2,6,0xa,0x500a,0xa,0xd00a,0xa,0xa,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0x500a,0xa,0xd00a,0xa,0x300a,0xf00a,0xa,0x300a,0xf00a,0xa,0xa,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,4,4,0xa,0xa,0xa,4,4,0,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+0x12,0xaa,0xaa,0xaa,0xa,0xa,0x12,0x12,0,0xa,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0,0,0,0,0,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0,0,0,0,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,0xa,1,0xb1,0xb1,0xb1,1,0xb1,0xb1,1,
+1,1,1,1,0xb1,0xb1,0xb1,0xb1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+0xb1,0xb1,0xb1,1,1,1,1,0xb1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,0xa,0xa,0xa,0xa,0xa,0xa,0xa,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,1,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0,
+0,0xb1,0xb1,0,0,0xa0,0,0,0,0,0,0,0,0,0,0xb1,
+0xb1,0xb1,0,0,0,0,0,0,0,0,0,0xb2,0xb2,0xb2,0xb2,0xb2,
+0xb2,0xb2,0xb2,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0,0,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0xb1,0xb1,0xb1,0xb1,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xa,0xa,0xb1,0xb1,0xb1,0xa,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0x100a,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0x100a,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0x100a,0,0,0,0,0,0,0,0,0,0,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0,0,0,0,
+0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xa,
+2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0x12,0x12,0x12,0xb2,0x12,0x12,
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0xb2,0xb2,0xb2,0xb2,
+0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,
+0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0xb2,0x12,0x12,0x12,0x12,
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0xb1,0xb1,0xb1,0xb1,
+0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0x12,0x12,0x12,0x12,
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0,0,0,0
+};
+
+static const uint32_t ubidi_props_mirrors[26]={
+0x2000ab,0xbb,0x2a02215,0x1202243,0x2802298,0x2c022a6,0x30022a8,0x2e022a9,0x32022ab,0x6022cd,0x1e022f2,0x20022f3,0x22022f4,0x24022f6,0x26022f7,0x14022fa,
+0x16022fb,0x18022fc,0x1a022fd,0x1c022fe,0x8029b8,0x4029f5,0xa02ade,0xe02ae3,0xc02ae4,0x1002ae5
+};
+
+static const uint8_t ubidi_props_jgArray[352]={
+3,3,0x2c,3,0x2d,3,4,0x2a,4,4,0xd,0xd,0xd,6,6,0x1f,
+0x1f,0x23,0x23,0x21,0x21,0x28,0x28,1,1,0xb,0xb,0x37,0x37,0x37,0,9,
+0x1d,0x13,0x16,0x18,0x1a,0x10,0x2c,0x2d,0x2d,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,4,0x1d,0,3,
+3,3,0,3,0x2c,0x2c,0x2d,4,4,4,4,4,4,4,4,0xd,
+0xd,0xd,0xd,0xd,0xd,0xd,6,6,6,6,6,6,6,6,6,0x1f,
+0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x23,0x23,0x23,0x21,0x21,0x28,1,9,
+9,9,9,9,9,0x1d,0x1d,0xb,0x26,0xb,0x13,0x13,0x13,0xb,0xb,0xb,
+0xb,0xb,0xb,0x16,0x16,0x16,0x16,0x1a,0x1a,0x1a,0x1a,0x38,0x15,0xd,0x2a,0x11,
+0x11,0xe,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x37,0x2f,0x37,0x2c,0x2d,0x2d,
+0x2e,0x2e,0,0x2a,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,6,0x1f,0,0,
+0,0,0,0,0,0,0,0,0x23,0x21,1,0,0,0x15,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,
+5,0xc,0xc,7,7,0xf,0x27,0x32,0x12,0x2b,0x2b,0x30,0x31,0x14,0x17,0x19,
+0x1b,0x24,0xa,8,0x1c,0x20,0x22,0x1e,7,0x25,0x29,5,0xc,7,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0x35,0x34,0x33,4,4,
+4,4,4,4,4,0xd,0xd,6,6,0x1f,0x23,1,1,1,9,9,
+0xb,0xb,0xb,0x18,0x18,0x1a,0x1a,0x1a,0x16,0x1f,0x1f,0x23,0xd,0xd,0x23,0x1f,
+0xd,3,3,0x37,0x37,0x2d,0x2c,0x2c,0x36,0x36,0xd,0x23,0x23,0x13,0,0
+};
+
+static const UBiDiProps ubidi_props_singleton={
+  NULL,
+  ubidi_props_indexes,
+  ubidi_props_mirrors,
+  ubidi_props_jgArray,
+  {
+    ubidi_props_trieIndex,
+    ubidi_props_trieIndex+3088,
+    NULL,
+    3088,
+    6544,
+    0x1a0,
+    0xc90,
+    0x0,
+    0x0,
+    0x110000,
+    0x259c,
+    NULL, 0, FALSE, FALSE, 0, NULL
+  },
+  { 2,0,0,0 }
+};
diff --git a/icu/source/common/ubidiimp.h b/icu/source/common/ubidiimp.h
new file mode 100644
index 0000000..1f1dcaa
--- /dev/null
+++ b/icu/source/common/ubidiimp.h
@@ -0,0 +1,385 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1999-2007, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*   file name:  ubidiimp.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 1999aug06
+*   created by: Markus W. Scherer, updated by Matitiahu Allouche
+*/
+
+#ifndef UBIDIIMP_H
+#define UBIDIIMP_H
+
+/* set import/export definitions */
+#ifdef U_COMMON_IMPLEMENTATION
+
+#include "unicode/utypes.h"
+#include "unicode/uchar.h"
+#include "ubidi_props.h"
+
+/* miscellaneous definitions ---------------------------------------------- */
+
+typedef uint8_t DirProp;
+typedef uint32_t Flags;
+
+/*  Comparing the description of the BiDi algorithm with this implementation
+    is easier with the same names for the BiDi types in the code as there.
+    See UCharDirection in uchar.h .
+*/
+enum {
+    L=  U_LEFT_TO_RIGHT,
+    R=  U_RIGHT_TO_LEFT,
+    EN= U_EUROPEAN_NUMBER,
+    ES= U_EUROPEAN_NUMBER_SEPARATOR,
+    ET= U_EUROPEAN_NUMBER_TERMINATOR,
+    AN= U_ARABIC_NUMBER,
+    CS= U_COMMON_NUMBER_SEPARATOR,
+    B=  U_BLOCK_SEPARATOR,
+    S=  U_SEGMENT_SEPARATOR,
+    WS= U_WHITE_SPACE_NEUTRAL,
+    ON= U_OTHER_NEUTRAL,
+    LRE=U_LEFT_TO_RIGHT_EMBEDDING,
+    LRO=U_LEFT_TO_RIGHT_OVERRIDE,
+    AL= U_RIGHT_TO_LEFT_ARABIC,
+    RLE=U_RIGHT_TO_LEFT_EMBEDDING,
+    RLO=U_RIGHT_TO_LEFT_OVERRIDE,
+    PDF=U_POP_DIRECTIONAL_FORMAT,
+    NSM=U_DIR_NON_SPACING_MARK,
+    BN= U_BOUNDARY_NEUTRAL,
+    dirPropCount
+};
+
+/*
+ * Sometimes, bit values are more appropriate
+ * to deal with directionality properties.
+ * Abbreviations in these macro names refer to names
+ * used in the BiDi algorithm.
+ */
+#define DIRPROP_FLAG(dir) (1UL<<(dir))
+
+/* special flag for multiple runs from explicit embedding codes */
+#define DIRPROP_FLAG_MULTI_RUNS (1UL<<31)
+
+/* are there any characters that are LTR or RTL? */
+#define MASK_LTR (DIRPROP_FLAG(L)|DIRPROP_FLAG(EN)|DIRPROP_FLAG(AN)|DIRPROP_FLAG(LRE)|DIRPROP_FLAG(LRO))
+#define MASK_RTL (DIRPROP_FLAG(R)|DIRPROP_FLAG(AL)|DIRPROP_FLAG(RLE)|DIRPROP_FLAG(RLO))
+#define MASK_R_AL (DIRPROP_FLAG(R)|DIRPROP_FLAG(AL))
+
+/* explicit embedding codes */
+#define MASK_LRX (DIRPROP_FLAG(LRE)|DIRPROP_FLAG(LRO))
+#define MASK_RLX (DIRPROP_FLAG(RLE)|DIRPROP_FLAG(RLO))
+#define MASK_OVERRIDE (DIRPROP_FLAG(LRO)|DIRPROP_FLAG(RLO))
+
+#define MASK_EXPLICIT (MASK_LRX|MASK_RLX|DIRPROP_FLAG(PDF))
+#define MASK_BN_EXPLICIT (DIRPROP_FLAG(BN)|MASK_EXPLICIT)
+
+/* paragraph and segment separators */
+#define MASK_B_S (DIRPROP_FLAG(B)|DIRPROP_FLAG(S))
+
+/* all types that are counted as White Space or Neutral in some steps */
+#define MASK_WS (MASK_B_S|DIRPROP_FLAG(WS)|MASK_BN_EXPLICIT)
+#define MASK_N (DIRPROP_FLAG(ON)|MASK_WS)
+
+/* all types that are included in a sequence of European Terminators for (W5) */
+#define MASK_ET_NSM_BN (DIRPROP_FLAG(ET)|DIRPROP_FLAG(NSM)|MASK_BN_EXPLICIT)
+
+/* types that are neutrals or could becomes neutrals in (Wn) */
+#define MASK_POSSIBLE_N (DIRPROP_FLAG(CS)|DIRPROP_FLAG(ES)|DIRPROP_FLAG(ET)|MASK_N)
+
+/*
+ * These types may be changed to "e",
+ * the embedding type (L or R) of the run,
+ * in the BiDi algorithm (N2)
+ */
+#define MASK_EMBEDDING (DIRPROP_FLAG(NSM)|MASK_POSSIBLE_N)
+
+/* the dirProp's L and R are defined to 0 and 1 values in UCharDirection */
+#define GET_LR_FROM_LEVEL(level) ((DirProp)((level)&1))
+
+#define IS_DEFAULT_LEVEL(level) ((level)>=0xfe)
+
+/*
+ * The following bit is ORed to the property of characters in paragraphs
+ * with contextual RTL direction when paraLevel is contextual.
+ */
+#define CONTEXT_RTL 0x80
+#define NO_CONTEXT_RTL(dir) ((dir)&~CONTEXT_RTL)
+/*
+ * The following is a variant of DIRPROP_FLAG which ignores the CONTEXT_RTL bit.
+ */
+#define DIRPROP_FLAG_NC(dir) (1UL<<(NO_CONTEXT_RTL(dir)))
+
+#define GET_PARALEVEL(ubidi, index) \
+            (UBiDiLevel)((ubidi)->defaultParaLevel ? (ubidi)->dirProps[index]>>7 \
+                                                   : (ubidi)->paraLevel)
+
+/* Paragraph type for multiple paragraph support ---------------------------- */
+typedef int32_t Para;
+
+#define CR  0x000D
+#define LF  0x000A
+
+/* Run structure for reordering --------------------------------------------- */
+enum {
+    LRM_BEFORE=1,
+    LRM_AFTER=2,
+    RLM_BEFORE=4,
+    RLM_AFTER=8
+};
+
+typedef struct Run {
+    int32_t logicalStart,   /* first character of the run; b31 indicates even/odd level */
+            visualLimit,    /* last visual position of the run +1 */
+            insertRemove;   /* if >0, flags for inserting LRM/RLM before/after run,
+                               if <0, count of bidi controls within run            */
+} Run;
+
+/* in a Run, logicalStart will get this bit set if the run level is odd */
+#define INDEX_ODD_BIT (1UL<<31)
+
+#define MAKE_INDEX_ODD_PAIR(index, level) ((index)|((int32_t)(level)<<31))
+#define ADD_ODD_BIT_FROM_LEVEL(x, level)  ((x)|=((int32_t)(level)<<31))
+#define REMOVE_ODD_BIT(x)                 ((x)&=~INDEX_ODD_BIT)
+
+#define GET_INDEX(x)   ((x)&~INDEX_ODD_BIT)
+#define GET_ODD_BIT(x) ((uint32_t)(x)>>31)
+#define IS_ODD_RUN(x)  ((UBool)(((x)&INDEX_ODD_BIT)!=0))
+#define IS_EVEN_RUN(x) ((UBool)(((x)&INDEX_ODD_BIT)==0))
+
+U_CFUNC UBool
+ubidi_getRuns(UBiDi *pBiDi, UErrorCode *pErrorCode);
+
+/** BiDi control code points */
+enum {
+    ZWNJ_CHAR=0x200c,
+    ZWJ_CHAR,
+    LRM_CHAR,
+    RLM_CHAR,
+    LRE_CHAR=0x202a,
+    RLE_CHAR,
+    PDF_CHAR,
+    LRO_CHAR,
+    RLO_CHAR
+};
+
+#define IS_BIDI_CONTROL_CHAR(c) (((uint32_t)(c)&0xfffffffc)==ZWNJ_CHAR || (uint32_t)((c)-LRE_CHAR)<5)
+
+/* InsertPoints structure for noting where to put BiDi marks ---------------- */
+
+typedef struct Point {
+    int32_t pos;            /* position in text */
+    int32_t flag;           /* flag for LRM/RLM, before/after */
+} Point;
+
+typedef struct InsertPoints {
+    int32_t capacity;       /* number of points allocated */
+    int32_t size;           /* number of points used */
+    int32_t confirmed;      /* number of points confirmed */
+    UErrorCode errorCode;   /* for eventual memory shortage */
+    Point *points;          /* pointer to array of points */
+} InsertPoints;
+
+
+/* UBiDi structure ----------------------------------------------------------- */
+
+struct UBiDi {
+    /* pointer to parent paragraph object (pointer to self if this object is
+     * a paragraph object); set to NULL in a newly opened object; set to a
+     * real value after a successful execution of ubidi_setPara or ubidi_setLine
+     */
+    const UBiDi * pParaBiDi;
+
+    const UBiDiProps *bdp;
+
+    /* alias pointer to the current text */
+    const UChar *text;
+
+    /* length of the current text */
+    int32_t originalLength;
+
+    /* if the UBIDI_OPTION_STREAMING option is set, this is the length
+     * of text actually processed by ubidi_setPara, which may be shorter than
+     * the original length.
+     * Otherwise, it is identical to the original length.
+     */
+    int32_t length;
+
+    /* if the UBIDI_OPTION_REMOVE_CONTROLS option is set, and/or
+     * marks are allowed to be inserted in one of the reordering mode, the
+     * length of the result string may be different from the processed length.
+     */
+    int32_t resultLength;
+
+    /* memory sizes in bytes */
+    int32_t dirPropsSize, levelsSize, parasSize, runsSize;
+
+    /* allocated memory */
+    DirProp *dirPropsMemory;
+    UBiDiLevel *levelsMemory;
+    Para *parasMemory;
+    Run *runsMemory;
+
+    /* indicators for whether memory may be allocated after ubidi_open() */
+    UBool mayAllocateText, mayAllocateRuns;
+
+    /* arrays with one value per text-character */
+    const DirProp *dirProps;
+    UBiDiLevel *levels;
+
+    /* are we performing an approximation of the "inverse BiDi" algorithm? */
+    UBool isInverse;
+
+    /* are we using the basic algorithm or its variation? */
+    UBiDiReorderingMode reorderingMode;
+
+    /* UBIDI_REORDER_xxx values must be ordered so that all the regular
+     * logical to visual modes come first, and all inverse BiDi modes
+     * come last.
+     */
+    #define UBIDI_REORDER_LAST_LOGICAL_TO_VISUAL    UBIDI_REORDER_NUMBERS_SPECIAL
+
+    /* bitmask for reordering options */
+    uint32_t reorderingOptions;
+
+    /* must block separators receive level 0? */
+    UBool orderParagraphsLTR;
+
+    /* the paragraph level */
+    UBiDiLevel paraLevel;
+    /* original paraLevel when contextual */
+    /* must be one of UBIDI_DEFAULT_xxx or 0 if not contextual */
+    UBiDiLevel defaultParaLevel;
+
+    /* the following is set in ubidi_setPara, used in processPropertySeq */
+    const struct ImpTabPair * pImpTabPair;  /* pointer to levels state table pair */
+
+    /* the overall paragraph or line directionality - see UBiDiDirection */
+    UBiDiDirection direction;
+
+    /* flags is a bit set for which directional properties are in the text */
+    Flags flags;
+
+    /* lastArabicPos is index to the last AL in the text, -1 if none */
+    int32_t lastArabicPos;
+
+    /* characters after trailingWSStart are WS and are */
+    /* implicitly at the paraLevel (rule (L1)) - levels may not reflect that */
+    int32_t trailingWSStart;
+
+    /* fields for paragraph handling */
+    int32_t paraCount;                  /* set in getDirProps() */
+    Para *paras;                        /* limits of paragraphs, filled in
+                            ResolveExplicitLevels() or CheckExplicitLevels() */
+
+    /* for single paragraph text, we only need a tiny array of paras (no malloc()) */
+    Para simpleParas[1];
+
+    /* fields for line reordering */
+    int32_t runCount;     /* ==-1: runs not set up yet */
+    Run *runs;
+
+    /* for non-mixed text, we only need a tiny array of runs (no malloc()) */
+    Run simpleRuns[1];
+
+    /* for inverse Bidi with insertion of directional marks */
+    InsertPoints insertPoints;
+
+    /* for option UBIDI_OPTION_REMOVE_CONTROLS */
+    int32_t controlCount;
+
+    /* for Bidi class callback */
+    UBiDiClassCallback *fnClassCallback;    /* action pointer */
+    const void *coClassCallback;            /* context pointer */
+};
+
+#define IS_VALID_PARA(x) ((x) && ((x)->pParaBiDi==(x)))
+#define IS_VALID_PARA_OR_LINE(x) ((x) && ((x)->pParaBiDi==(x) || (((x)->pParaBiDi) && (x)->pParaBiDi->pParaBiDi==(x)->pParaBiDi)))
+
+typedef union {
+    DirProp *dirPropsMemory;
+    UBiDiLevel *levelsMemory;
+    Para *parasMemory;
+    Run *runsMemory;
+} BidiMemoryForAllocation;
+
+/* Macros for initial checks at function entry */
+#define RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrcode, retvalue)   \
+        if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return retvalue
+#define RETURN_IF_NOT_VALID_PARA(bidi, errcode, retvalue)   \
+        if(!IS_VALID_PARA(bidi)) {  \
+            errcode=U_INVALID_STATE_ERROR;  \
+            return retvalue;                \
+        }
+#define RETURN_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode, retvalue)   \
+        if(!IS_VALID_PARA_OR_LINE(bidi)) {  \
+            errcode=U_INVALID_STATE_ERROR;  \
+            return retvalue;                \
+        }
+#define RETURN_IF_BAD_RANGE(arg, start, limit, errcode, retvalue)   \
+        if((arg)<(start) || (arg)>=(limit)) {       \
+            (errcode)=U_ILLEGAL_ARGUMENT_ERROR;     \
+            return retvalue;                        \
+        }
+
+#define RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrcode)   \
+        if((pErrcode)==NULL || U_FAILURE(*pErrcode)) return
+#define RETURN_VOID_IF_NOT_VALID_PARA(bidi, errcode)   \
+        if(!IS_VALID_PARA(bidi)) {  \
+            errcode=U_INVALID_STATE_ERROR;  \
+            return;                \
+        }
+#define RETURN_VOID_IF_NOT_VALID_PARA_OR_LINE(bidi, errcode)   \
+        if(!IS_VALID_PARA_OR_LINE(bidi)) {  \
+            errcode=U_INVALID_STATE_ERROR;  \
+            return;                \
+        }
+#define RETURN_VOID_IF_BAD_RANGE(arg, start, limit, errcode)   \
+        if((arg)<(start) || (arg)>=(limit)) {       \
+            (errcode)=U_ILLEGAL_ARGUMENT_ERROR;     \
+            return;                        \
+        }
+
+/* helper function to (re)allocate memory if allowed */
+U_CFUNC UBool
+ubidi_getMemory(BidiMemoryForAllocation *pMemory, int32_t *pSize, UBool mayAllocate, int32_t sizeNeeded);
+
+/* helper macros for each allocated array in UBiDi */
+#define getDirPropsMemory(pBiDi, length) \
+        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->dirPropsMemory, &(pBiDi)->dirPropsSize, \
+                        (pBiDi)->mayAllocateText, (length))
+
+#define getLevelsMemory(pBiDi, length) \
+        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->levelsMemory, &(pBiDi)->levelsSize, \
+                        (pBiDi)->mayAllocateText, (length))
+
+#define getRunsMemory(pBiDi, length) \
+        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->runsMemory, &(pBiDi)->runsSize, \
+                        (pBiDi)->mayAllocateRuns, (length)*sizeof(Run))
+
+/* additional macros used by ubidi_open() - always allow allocation */
+#define getInitialDirPropsMemory(pBiDi, length) \
+        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->dirPropsMemory, &(pBiDi)->dirPropsSize, \
+                        TRUE, (length))
+
+#define getInitialLevelsMemory(pBiDi, length) \
+        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->levelsMemory, &(pBiDi)->levelsSize, \
+                        TRUE, (length))
+
+#define getInitialParasMemory(pBiDi, length) \
+        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->parasMemory, &(pBiDi)->parasSize, \
+                        TRUE, (length)*sizeof(Para))
+
+#define getInitialRunsMemory(pBiDi, length) \
+        ubidi_getMemory((BidiMemoryForAllocation *)&(pBiDi)->runsMemory, &(pBiDi)->runsSize, \
+                        TRUE, (length)*sizeof(Run))
+
+#endif
+
+#endif
diff --git a/icu/source/common/ubidiln.c b/icu/source/common/ubidiln.c
new file mode 100644
index 0000000..6ddf322
--- /dev/null
+++ b/icu/source/common/ubidiln.c
@@ -0,0 +1,1346 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1999-2009, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*   file name:  ubidiln.c
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 1999aug06
+*   created by: Markus W. Scherer, updated by Matitiahu Allouche
+*/
+
+#include "cmemory.h"
+#include "unicode/utypes.h"
+#include "unicode/ustring.h"
+#include "unicode/uchar.h"
+#include "unicode/ubidi.h"
+#include "ubidiimp.h"
+#include "uassert.h"
+
+/*
+ * General remarks about the functions in this file:
+ *
+ * These functions deal with the aspects of potentially mixed-directional
+ * text in a single paragraph or in a line of a single paragraph
+ * which has already been processed according to
+ * the Unicode 3.0 BiDi algorithm as defined in
+ * http://www.unicode.org/unicode/reports/tr9/ , version 13,
+ * also described in The Unicode Standard, Version 4.0.1 .
+ *
+ * This means that there is a UBiDi object with a levels
+ * and a dirProps array.
+ * paraLevel and direction are also set.
+ * Only if the length of the text is zero, then levels==dirProps==NULL.
+ *
+ * The overall directionality of the paragraph
+ * or line is used to bypass the reordering steps if possible.
+ * Even purely RTL text does not need reordering there because
+ * the ubidi_getLogical/VisualIndex() functions can compute the
+ * index on the fly in such a case.
+ *
+ * The implementation of the access to same-level-runs and of the reordering
+ * do attempt to provide better performance and less memory usage compared to
+ * a direct implementation of especially rule (L2) with an array of
+ * one (32-bit) integer per text character.
+ *
+ * Here, the levels array is scanned as soon as necessary, and a vector of
+ * same-level-runs is created. Reordering then is done on this vector.
+ * For each run of text positions that were resolved to the same level,
+ * only 8 bytes are stored: the first text position of the run and the visual
+ * position behind the run after reordering.
+ * One sign bit is used to hold the directionality of the run.
+ * This is inefficient if there are many very short runs. If the average run
+ * length is <2, then this uses more memory.
+ *
+ * In a further attempt to save memory, the levels array is never changed
+ * after all the resolution rules (Xn, Wn, Nn, In).
+ * Many functions have to consider the field trailingWSStart:
+ * if it is less than length, then there is an implicit trailing run
+ * at the paraLevel,
+ * which is not reflected in the levels array.
+ * This allows a line UBiDi object to use the same levels array as
+ * its paragraph parent object.
+ *
+ * When a UBiDi object is created for a line of a paragraph, then the
+ * paragraph's levels and dirProps arrays are reused by way of setting
+ * a pointer into them, not by copying. This again saves memory and forbids to
+ * change the now shared levels for (L1).
+ */
+
+/* handle trailing WS (L1) -------------------------------------------------- */
+
+/*
+ * setTrailingWSStart() sets the start index for a trailing
+ * run of WS in the line. This is necessary because we do not modify
+ * the paragraph's levels array that we just point into.
+ * Using trailingWSStart is another form of performing (L1).
+ *
+ * To make subsequent operations easier, we also include the run
+ * before the WS if it is at the paraLevel - we merge the two here.
+ *
+ * This function is called only from ubidi_setLine(), so pBiDi->paraLevel is
+ * set correctly for the line even when contextual multiple paragraphs.
+ */
+static void
+setTrailingWSStart(UBiDi *pBiDi) {
+    /* pBiDi->direction!=UBIDI_MIXED */
+
+    const DirProp *dirProps=pBiDi->dirProps;
+    UBiDiLevel *levels=pBiDi->levels;
+    int32_t start=pBiDi->length;
+    UBiDiLevel paraLevel=pBiDi->paraLevel;
+
+    /* If the line is terminated by a block separator, all preceding WS etc...
+       are already set to paragraph level.
+       Setting trailingWSStart to pBidi->length will avoid changing the
+       level of B chars from 0 to paraLevel in ubidi_getLevels when
+       orderParagraphsLTR==TRUE.
+     */
+    if(NO_CONTEXT_RTL(dirProps[start-1])==B) {
+        pBiDi->trailingWSStart=start;   /* currently == pBiDi->length */
+        return;
+    }
+    /* go backwards across all WS, BN, explicit codes */
+    while(start>0 && DIRPROP_FLAG_NC(dirProps[start-1])&MASK_WS) {
+        --start;
+    }
+
+    /* if the WS run can be merged with the previous run then do so here */
+    while(start>0 && levels[start-1]==paraLevel) {
+        --start;
+    }
+
+    pBiDi->trailingWSStart=start;
+}
+
+/* ubidi_setLine ------------------------------------------------------------ */
+
+U_CAPI void U_EXPORT2
+ubidi_setLine(const UBiDi *pParaBiDi,
+              int32_t start, int32_t limit,
+              UBiDi *pLineBiDi,
+              UErrorCode *pErrorCode) {
+    int32_t length;
+
+    /* check the argument values */
+    RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrorCode);
+    RETURN_VOID_IF_NOT_VALID_PARA(pParaBiDi, *pErrorCode);
+    RETURN_VOID_IF_BAD_RANGE(start, 0, limit, *pErrorCode);
+    RETURN_VOID_IF_BAD_RANGE(limit, 0, pParaBiDi->length+1, *pErrorCode);
+    if(pLineBiDi==NULL) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    if(ubidi_getParagraph(pParaBiDi, start, NULL, NULL, NULL, pErrorCode) !=
+       ubidi_getParagraph(pParaBiDi, limit-1, NULL, NULL, NULL, pErrorCode)) {
+        /* the line crosses a paragraph boundary */
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    /* set the values in pLineBiDi from its pParaBiDi parent */
+    pLineBiDi->pParaBiDi=NULL;          /* mark unfinished setLine */
+    pLineBiDi->text=pParaBiDi->text+start;
+    length=pLineBiDi->length=limit-start;
+    pLineBiDi->resultLength=pLineBiDi->originalLength=length;
+    pLineBiDi->paraLevel=GET_PARALEVEL(pParaBiDi, start);
+    pLineBiDi->paraCount=pParaBiDi->paraCount;
+    pLineBiDi->runs=NULL;
+    pLineBiDi->flags=0;
+    pLineBiDi->reorderingMode=pParaBiDi->reorderingMode;
+    pLineBiDi->reorderingOptions=pParaBiDi->reorderingOptions;
+    pLineBiDi->controlCount=0;
+    if(pParaBiDi->controlCount>0) {
+        int32_t j;
+        for(j=start; j<limit; j++) {
+            if(IS_BIDI_CONTROL_CHAR(pParaBiDi->text[j])) {
+                pLineBiDi->controlCount++;
+            }
+        }
+        pLineBiDi->resultLength-=pLineBiDi->controlCount;
+    }
+
+    pLineBiDi->dirProps=pParaBiDi->dirProps+start;
+    pLineBiDi->levels=pParaBiDi->levels+start;
+    pLineBiDi->runCount=-1;
+
+    if(pParaBiDi->direction!=UBIDI_MIXED) {
+        /* the parent is already trivial */
+        pLineBiDi->direction=pParaBiDi->direction;
+
+        /*
+         * The parent's levels are all either
+         * implicitly or explicitly ==paraLevel;
+         * do the same here.
+         */
+        if(pParaBiDi->trailingWSStart<=start) {
+            pLineBiDi->trailingWSStart=0;
+        } else if(pParaBiDi->trailingWSStart<limit) {
+            pLineBiDi->trailingWSStart=pParaBiDi->trailingWSStart-start;
+        } else {
+            pLineBiDi->trailingWSStart=length;
+        }
+    } else {
+        const UBiDiLevel *levels=pLineBiDi->levels;
+        int32_t i, trailingWSStart;
+        UBiDiLevel level;
+
+        setTrailingWSStart(pLineBiDi);
+        trailingWSStart=pLineBiDi->trailingWSStart;
+
+        /* recalculate pLineBiDi->direction */
+        if(trailingWSStart==0) {
+            /* all levels are at paraLevel */
+            pLineBiDi->direction=(UBiDiDirection)(pLineBiDi->paraLevel&1);
+        } else {
+            /* get the level of the first character */
+            level=(UBiDiLevel)(levels[0]&1);
+
+            /* if there is anything of a different level, then the line is mixed */
+            if(trailingWSStart<length && (pLineBiDi->paraLevel&1)!=level) {
+                /* the trailing WS is at paraLevel, which differs from levels[0] */
+                pLineBiDi->direction=UBIDI_MIXED;
+            } else {
+                /* see if levels[1..trailingWSStart-1] have the same direction as levels[0] and paraLevel */
+                i=1;
+                for(;;) {
+                    if(i==trailingWSStart) {
+                        /* the direction values match those in level */
+                        pLineBiDi->direction=(UBiDiDirection)level;
+                        break;
+                    } else if((levels[i]&1)!=level) {
+                        pLineBiDi->direction=UBIDI_MIXED;
+                        break;
+                    }
+                    ++i;
+                }
+            }
+        }
+
+        switch(pLineBiDi->direction) {
+        case UBIDI_LTR:
+            /* make sure paraLevel is even */
+            pLineBiDi->paraLevel=(UBiDiLevel)((pLineBiDi->paraLevel+1)&~1);
+
+            /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */
+            pLineBiDi->trailingWSStart=0;
+            break;
+        case UBIDI_RTL:
+            /* make sure paraLevel is odd */
+            pLineBiDi->paraLevel|=1;
+
+            /* all levels are implicitly at paraLevel (important for ubidi_getLevels()) */
+            pLineBiDi->trailingWSStart=0;
+            break;
+        default:
+            break;
+        }
+    }
+    pLineBiDi->pParaBiDi=pParaBiDi;     /* mark successful setLine */
+    return;
+}
+
+U_CAPI UBiDiLevel U_EXPORT2
+ubidi_getLevelAt(const UBiDi *pBiDi, int32_t charIndex) {
+    /* return paraLevel if in the trailing WS run, otherwise the real level */
+    if(!IS_VALID_PARA_OR_LINE(pBiDi) || charIndex<0 || pBiDi->length<=charIndex) {
+        return 0;
+    } else if(pBiDi->direction!=UBIDI_MIXED || charIndex>=pBiDi->trailingWSStart) {
+        return GET_PARALEVEL(pBiDi, charIndex);
+    } else {
+        return pBiDi->levels[charIndex];
+    }
+}
+
+U_CAPI const UBiDiLevel * U_EXPORT2
+ubidi_getLevels(UBiDi *pBiDi, UErrorCode *pErrorCode) {
+    int32_t start, length;
+
+    RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrorCode, NULL);
+    RETURN_IF_NOT_VALID_PARA_OR_LINE(pBiDi, *pErrorCode, NULL);
+    if((length=pBiDi->length)<=0) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return NULL;
+    }
+    if((start=pBiDi->trailingWSStart)==length) {
+        /* the current levels array reflects the WS run */
+        return pBiDi->levels;
+    }
+
+    /*
+     * After the previous if(), we know that the levels array
+     * has an implicit trailing WS run and therefore does not fully
+     * reflect itself all the levels.
+     * This must be a UBiDi object for a line, and
+     * we need to create a new levels array.
+     */
+    if(getLevelsMemory(pBiDi, length)) {
+        UBiDiLevel *levels=pBiDi->levelsMemory;
+
+        if(start>0 && levels!=pBiDi->levels) {
+            uprv_memcpy(levels, pBiDi->levels, start);
+        }
+        /* pBiDi->paraLevel is ok even if contextual multiple paragraphs,
+           since pBidi is a line object                                     */
+        uprv_memset(levels+start, pBiDi->paraLevel, length-start);
+
+        /* this new levels array is set for the line and reflects the WS run */
+        pBiDi->trailingWSStart=length;
+        return pBiDi->levels=levels;
+    } else {
+        /* out of memory */
+        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
+    }
+}
+
+U_CAPI void U_EXPORT2
+ubidi_getLogicalRun(const UBiDi *pBiDi, int32_t logicalPosition,
+                    int32_t *pLogicalLimit, UBiDiLevel *pLevel) {
+    UErrorCode errorCode;
+    int32_t runCount, visualStart, logicalLimit, logicalFirst, i;
+    Run iRun;
+
+    errorCode=U_ZERO_ERROR;
+    RETURN_VOID_IF_BAD_RANGE(logicalPosition, 0, pBiDi->length, errorCode);
+    /* ubidi_countRuns will check VALID_PARA_OR_LINE */
+    runCount=ubidi_countRuns((UBiDi *)pBiDi, &errorCode);
+    if(U_FAILURE(errorCode)) {
+        return;
+    }
+    /* this is done based on runs rather than on levels since levels have
+       a special interpretation when UBIDI_REORDER_RUNS_ONLY
+     */
+    visualStart=logicalLimit=0;
+    iRun=pBiDi->runs[0];
+
+    for(i=0; i<runCount; i++) {
+        iRun = pBiDi->runs[i];
+        logicalFirst=GET_INDEX(iRun.logicalStart);
+        logicalLimit=logicalFirst+iRun.visualLimit-visualStart;
+        if((logicalPosition>=logicalFirst) &&
+           (logicalPosition<logicalLimit)) {
+            break;
+        }
+        visualStart = iRun.visualLimit;
+    }
+    if(pLogicalLimit) {
+        *pLogicalLimit=logicalLimit;
+    }
+    if(pLevel) {
+        if(pBiDi->reorderingMode==UBIDI_REORDER_RUNS_ONLY) {
+            *pLevel=(UBiDiLevel)GET_ODD_BIT(iRun.logicalStart);
+        }
+        else if(pBiDi->direction!=UBIDI_MIXED || logicalPosition>=pBiDi->trailingWSStart) {
+            *pLevel=GET_PARALEVEL(pBiDi, logicalPosition);
+        } else {
+        *pLevel=pBiDi->levels[logicalPosition];
+        }
+    }
+}
+
+/* runs API functions ------------------------------------------------------- */
+
+U_CAPI int32_t U_EXPORT2
+ubidi_countRuns(UBiDi *pBiDi, UErrorCode *pErrorCode) {
+    RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrorCode, -1);
+    RETURN_IF_NOT_VALID_PARA_OR_LINE(pBiDi, *pErrorCode, -1);
+    ubidi_getRuns(pBiDi, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        return -1;
+    }
+    return pBiDi->runCount;
+}
+
+U_CAPI UBiDiDirection U_EXPORT2
+ubidi_getVisualRun(UBiDi *pBiDi, int32_t runIndex,
+                   int32_t *pLogicalStart, int32_t *pLength)
+{
+    int32_t start;
+    UErrorCode errorCode = U_ZERO_ERROR;
+    RETURN_IF_NOT_VALID_PARA_OR_LINE(pBiDi, errorCode, UBIDI_LTR);
+    ubidi_getRuns(pBiDi, &errorCode);
+    if(U_FAILURE(errorCode)) {
+        return UBIDI_LTR;
+    }
+    RETURN_IF_BAD_RANGE(runIndex, 0, pBiDi->runCount, errorCode, UBIDI_LTR);
+
+    start=pBiDi->runs[runIndex].logicalStart;
+    if(pLogicalStart!=NULL) {
+        *pLogicalStart=GET_INDEX(start);
+    }
+    if(pLength!=NULL) {
+        if(runIndex>0) {
+            *pLength=pBiDi->runs[runIndex].visualLimit-
+                     pBiDi->runs[runIndex-1].visualLimit;
+        } else {
+            *pLength=pBiDi->runs[0].visualLimit;
+        }
+    }
+    return (UBiDiDirection)GET_ODD_BIT(start);
+}
+
+/* in trivial cases there is only one trivial run; called by ubidi_getRuns() */
+static void
+getSingleRun(UBiDi *pBiDi, UBiDiLevel level) {
+    /* simple, single-run case */
+    pBiDi->runs=pBiDi->simpleRuns;
+    pBiDi->runCount=1;
+
+    /* fill and reorder the single run */
+    pBiDi->runs[0].logicalStart=MAKE_INDEX_ODD_PAIR(0, level);
+    pBiDi->runs[0].visualLimit=pBiDi->length;
+    pBiDi->runs[0].insertRemove=0;
+}
+
+/* reorder the runs array (L2) ---------------------------------------------- */
+
+/*
+ * Reorder the same-level runs in the runs array.
+ * Here, runCount>1 and maxLevel>=minLevel>=paraLevel.
+ * All the visualStart fields=logical start before reordering.
+ * The "odd" bits are not set yet.
+ *
+ * Reordering with this data structure lends itself to some handy shortcuts:
+ *
+ * Since each run is moved but not modified, and since at the initial maxLevel
+ * each sequence of same-level runs consists of only one run each, we
+ * don't need to do anything there and can predecrement maxLevel.
+ * In many simple cases, the reordering is thus done entirely in the
+ * index mapping.
+ * Also, reordering occurs only down to the lowest odd level that occurs,
+ * which is minLevel|1. However, if the lowest level itself is odd, then
+ * in the last reordering the sequence of the runs at this level or higher
+ * will be all runs, and we don't need the elaborate loop to search for them.
+ * This is covered by ++minLevel instead of minLevel|=1 followed
+ * by an extra reorder-all after the reorder-some loop.
+ * About a trailing WS run:
+ * Such a run would need special treatment because its level is not
+ * reflected in levels[] if this is not a paragraph object.
+ * Instead, all characters from trailingWSStart on are implicitly at
+ * paraLevel.
+ * However, for all maxLevel>paraLevel, this run will never be reordered
+ * and does not need to be taken into account. maxLevel==paraLevel is only reordered
+ * if minLevel==paraLevel is odd, which is done in the extra segment.
+ * This means that for the main reordering loop we don't need to consider
+ * this run and can --runCount. If it is later part of the all-runs
+ * reordering, then runCount is adjusted accordingly.
+ */
+static void
+reorderLine(UBiDi *pBiDi, UBiDiLevel minLevel, UBiDiLevel maxLevel) {
+    Run *runs, tempRun;
+    UBiDiLevel *levels;
+    int32_t firstRun, endRun, limitRun, runCount;
+
+    /* nothing to do? */
+    if(maxLevel<=(minLevel|1)) {
+        return;
+    }
+
+    /*
+     * Reorder only down to the lowest odd level
+     * and reorder at an odd minLevel in a separate, simpler loop.
+     * See comments above for why minLevel is always incremented.
+     */
+    ++minLevel;
+
+    runs=pBiDi->runs;
+    levels=pBiDi->levels;
+    runCount=pBiDi->runCount;
+
+    /* do not include the WS run at paraLevel<=old minLevel except in the simple loop */
+    if(pBiDi->trailingWSStart<pBiDi->length) {
+        --runCount;
+    }
+
+    while(--maxLevel>=minLevel) {
+        firstRun=0;
+
+        /* loop for all sequences of runs */
+        for(;;) {
+            /* look for a sequence of runs that are all at >=maxLevel */
+            /* look for the first run of such a sequence */
+            while(firstRun<runCount && levels[runs[firstRun].logicalStart]<maxLevel) {
+                ++firstRun;
+            }
+            if(firstRun>=runCount) {
+                break;  /* no more such runs */
+            }
+
+            /* look for the limit run of such a sequence (the run behind it) */
+            for(limitRun=firstRun; ++limitRun<runCount && levels[runs[limitRun].logicalStart]>=maxLevel;) {}
+
+            /* Swap the entire sequence of runs from firstRun to limitRun-1. */
+            endRun=limitRun-1;
+            while(firstRun<endRun) {
+                tempRun = runs[firstRun];
+                runs[firstRun]=runs[endRun];
+                runs[endRun]=tempRun;
+                ++firstRun;
+                --endRun;
+            }
+
+            if(limitRun==runCount) {
+                break;  /* no more such runs */
+            } else {
+                firstRun=limitRun+1;
+            }
+        }
+    }
+
+    /* now do maxLevel==old minLevel (==odd!), see above */
+    if(!(minLevel&1)) {
+        firstRun=0;
+
+        /* include the trailing WS run in this complete reordering */
+        if(pBiDi->trailingWSStart==pBiDi->length) {
+            --runCount;
+        }
+
+        /* Swap the entire sequence of all runs. (endRun==runCount) */
+        while(firstRun<runCount) {
+            tempRun=runs[firstRun];
+            runs[firstRun]=runs[runCount];
+            runs[runCount]=tempRun;
+            ++firstRun;
+            --runCount;
+        }
+    }
+}
+
+/* compute the runs array --------------------------------------------------- */
+
+static int32_t getRunFromLogicalIndex(UBiDi *pBiDi, int32_t logicalIndex, UErrorCode *pErrorCode) {
+    Run *runs=pBiDi->runs;
+    int32_t runCount=pBiDi->runCount, visualStart=0, i, length, logicalStart;
+
+    for(i=0; i<runCount; i++) {
+        length=runs[i].visualLimit-visualStart;
+        logicalStart=GET_INDEX(runs[i].logicalStart);
+        if((logicalIndex>=logicalStart) && (logicalIndex<(logicalStart+length))) {
+            return i;
+        }
+        visualStart+=length;
+    }
+    /* we should never get here */
+    U_ASSERT(FALSE);
+    *pErrorCode = U_INVALID_STATE_ERROR;
+    return 0;
+}
+
+/*
+ * Compute the runs array from the levels array.
+ * After ubidi_getRuns() returns TRUE, runCount is guaranteed to be >0
+ * and the runs are reordered.
+ * Odd-level runs have visualStart on their visual right edge and
+ * they progress visually to the left.
+ * If option UBIDI_OPTION_INSERT_MARKS is set, insertRemove will contain the
+ * sum of appropriate LRM/RLM_BEFORE/AFTER flags.
+ * If option UBIDI_OPTION_REMOVE_CONTROLS is set, insertRemove will contain the
+ * negative number of BiDi control characters within this run.
+ */
+U_CFUNC UBool
+ubidi_getRuns(UBiDi *pBiDi, UErrorCode *pErrorCode) {
+    /*
+     * This method returns immediately if the runs are already set. This
+     * includes the case of length==0 (handled in setPara)..
+     */
+    if (pBiDi->runCount>=0) {
+        return TRUE;
+    }
+
+    if(pBiDi->direction!=UBIDI_MIXED) {
+        /* simple, single-run case - this covers length==0 */
+        /* pBiDi->paraLevel is ok even for contextual multiple paragraphs */
+        getSingleRun(pBiDi, pBiDi->paraLevel);
+    } else /* UBIDI_MIXED, length>0 */ {
+        /* mixed directionality */
+        int32_t length=pBiDi->length, limit;
+        UBiDiLevel *levels=pBiDi->levels;
+        int32_t i, runCount;
+        UBiDiLevel level=UBIDI_DEFAULT_LTR;   /* initialize with no valid level */
+        /*
+         * If there are WS characters at the end of the line
+         * and the run preceding them has a level different from
+         * paraLevel, then they will form their own run at paraLevel (L1).
+         * Count them separately.
+         * We need some special treatment for this in order to not
+         * modify the levels array which a line UBiDi object shares
+         * with its paragraph parent and its other line siblings.
+         * In other words, for the trailing WS, it may be
+         * levels[]!=paraLevel but we have to treat it like it were so.
+         */
+        limit=pBiDi->trailingWSStart;
+        /* count the runs, there is at least one non-WS run, and limit>0 */
+        runCount=0;
+        for(i=0; i<limit; ++i) {
+            /* increment runCount at the start of each run */
+            if(levels[i]!=level) {
+                ++runCount;
+                level=levels[i];
+            }
+        }
+
+        /*
+         * We don't need to see if the last run can be merged with a trailing
+         * WS run because setTrailingWSStart() would have done that.
+         */
+        if(runCount==1 && limit==length) {
+            /* There is only one non-WS run and no trailing WS-run. */
+            getSingleRun(pBiDi, levels[0]);
+        } else /* runCount>1 || limit<length */ {
+            /* allocate and set the runs */
+            Run *runs;
+            int32_t runIndex, start;
+            UBiDiLevel minLevel=UBIDI_MAX_EXPLICIT_LEVEL+1, maxLevel=0;
+
+            /* now, count a (non-mergeable) WS run */
+            if(limit<length) {
+                ++runCount;
+            }
+
+            /* runCount>1 */
+            if(getRunsMemory(pBiDi, runCount)) {
+                runs=pBiDi->runsMemory;
+            } else {
+                return FALSE;
+            }
+
+            /* set the runs */
+            /* FOOD FOR THOUGHT: this could be optimized, e.g.:
+             * 464->444, 484->444, 575->555, 595->555
+             * However, that would take longer. Check also how it would
+             * interact with BiDi control removal and inserting Marks.
+             */
+            runIndex=0;
+
+            /* search for the run limits and initialize visualLimit values with the run lengths */
+            i=0;
+            do {
+                /* prepare this run */
+                start=i;
+                level=levels[i];
+                if(level<minLevel) {
+                    minLevel=level;
+                }
+                if(level>maxLevel) {
+                    maxLevel=level;
+                }
+
+                /* look for the run limit */
+                while(++i<limit && levels[i]==level) {}
+
+                /* i is another run limit */
+                runs[runIndex].logicalStart=start;
+                runs[runIndex].visualLimit=i-start;
+                runs[runIndex].insertRemove=0;
+                ++runIndex;
+            } while(i<limit);
+
+            if(limit<length) {
+                /* there is a separate WS run */
+                runs[runIndex].logicalStart=limit;
+                runs[runIndex].visualLimit=length-limit;
+                /* For the trailing WS run, pBiDi->paraLevel is ok even
+                   if contextual multiple paragraphs.                   */
+                if(pBiDi->paraLevel<minLevel) {
+                    minLevel=pBiDi->paraLevel;
+                }
+            }
+
+            /* set the object fields */
+            pBiDi->runs=runs;
+            pBiDi->runCount=runCount;
+
+            reorderLine(pBiDi, minLevel, maxLevel);
+
+            /* now add the direction flags and adjust the visualLimit's to be just that */
+            /* this loop will also handle the trailing WS run */
+            limit=0;
+            for(i=0; i<runCount; ++i) {
+                ADD_ODD_BIT_FROM_LEVEL(runs[i].logicalStart, levels[runs[i].logicalStart]);
+                limit=runs[i].visualLimit+=limit;
+            }
+
+            /* Set the "odd" bit for the trailing WS run. */
+            /* For a RTL paragraph, it will be the *first* run in visual order. */
+            /* For the trailing WS run, pBiDi->paraLevel is ok even if
+               contextual multiple paragraphs.                          */
+            if(runIndex<runCount) {
+                int32_t trailingRun = ((pBiDi->paraLevel & 1) != 0)? 0 : runIndex;
+
+                ADD_ODD_BIT_FROM_LEVEL(runs[trailingRun].logicalStart, pBiDi->paraLevel);
+            }
+        }
+    }
+
+    /* handle insert LRM/RLM BEFORE/AFTER run */
+    if(pBiDi->insertPoints.size>0) {
+        Point *point, *start=pBiDi->insertPoints.points,
+                      *limit=start+pBiDi->insertPoints.size;
+        int32_t runIndex;
+        for(point=start; point<limit; point++) {
+            runIndex=getRunFromLogicalIndex(pBiDi, point->pos, pErrorCode);
+            pBiDi->runs[runIndex].insertRemove|=point->flag;
+        }
+    }
+
+    /* handle remove BiDi control characters */
+    if(pBiDi->controlCount>0) {
+        int32_t runIndex;
+        const UChar *start=pBiDi->text, *limit=start+pBiDi->length, *pu;
+        for(pu=start; pu<limit; pu++) {
+            if(IS_BIDI_CONTROL_CHAR(*pu)) {
+                runIndex=getRunFromLogicalIndex(pBiDi, (int32_t)(pu-start), pErrorCode);
+                pBiDi->runs[runIndex].insertRemove--;
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+static UBool
+prepareReorder(const UBiDiLevel *levels, int32_t length,
+               int32_t *indexMap,
+               UBiDiLevel *pMinLevel, UBiDiLevel *pMaxLevel) {
+    int32_t start;
+    UBiDiLevel level, minLevel, maxLevel;
+
+    if(levels==NULL || length<=0) {
+        return FALSE;
+    }
+
+    /* determine minLevel and maxLevel */
+    minLevel=UBIDI_MAX_EXPLICIT_LEVEL+1;
+    maxLevel=0;
+    for(start=length; start>0;) {
+        level=levels[--start];
+        if(level>UBIDI_MAX_EXPLICIT_LEVEL+1) {
+            return FALSE;
+        }
+        if(level<minLevel) {
+            minLevel=level;
+        }
+        if(level>maxLevel) {
+            maxLevel=level;
+        }
+    }
+    *pMinLevel=minLevel;
+    *pMaxLevel=maxLevel;
+
+    /* initialize the index map */
+    for(start=length; start>0;) {
+        --start;
+        indexMap[start]=start;
+    }
+
+    return TRUE;
+}
+
+/* reorder a line based on a levels array (L2) ------------------------------ */
+
+U_CAPI void U_EXPORT2
+ubidi_reorderLogical(const UBiDiLevel *levels, int32_t length, int32_t *indexMap) {
+    int32_t start, limit, sumOfSosEos;
+    UBiDiLevel minLevel = 0, maxLevel = 0;
+
+    if(indexMap==NULL || !prepareReorder(levels, length, indexMap, &minLevel, &maxLevel)) {
+        return;
+    }
+
+    /* nothing to do? */
+    if(minLevel==maxLevel && (minLevel&1)==0) {
+        return;
+    }
+
+    /* reorder only down to the lowest odd level */
+    minLevel|=1;
+
+    /* loop maxLevel..minLevel */
+    do {
+        start=0;
+
+        /* loop for all sequences of levels to reorder at the current maxLevel */
+        for(;;) {
+            /* look for a sequence of levels that are all at >=maxLevel */
+            /* look for the first index of such a sequence */
+            while(start<length && levels[start]<maxLevel) {
+                ++start;
+            }
+            if(start>=length) {
+                break;  /* no more such sequences */
+            }
+
+            /* look for the limit of such a sequence (the index behind it) */
+            for(limit=start; ++limit<length && levels[limit]>=maxLevel;) {}
+
+            /*
+             * sos=start of sequence, eos=end of sequence
+             *
+             * The closed (inclusive) interval from sos to eos includes all the logical
+             * and visual indexes within this sequence. They are logically and
+             * visually contiguous and in the same range.
+             *
+             * For each run, the new visual index=sos+eos-old visual index;
+             * we pre-add sos+eos into sumOfSosEos ->
+             * new visual index=sumOfSosEos-old visual index;
+             */
+            sumOfSosEos=start+limit-1;
+
+            /* reorder each index in the sequence */
+            do {
+                indexMap[start]=sumOfSosEos-indexMap[start];
+            } while(++start<limit);
+
+            /* start==limit */
+            if(limit==length) {
+                break;  /* no more such sequences */
+            } else {
+                start=limit+1;
+            }
+        }
+    } while(--maxLevel>=minLevel);
+}
+
+U_CAPI void U_EXPORT2
+ubidi_reorderVisual(const UBiDiLevel *levels, int32_t length, int32_t *indexMap) {
+    int32_t start, end, limit, temp;
+    UBiDiLevel minLevel = 0, maxLevel = 0;
+
+    if(indexMap==NULL || !prepareReorder(levels, length, indexMap, &minLevel, &maxLevel)) {
+        return;
+    }
+
+    /* nothing to do? */
+    if(minLevel==maxLevel && (minLevel&1)==0) {
+        return;
+    }
+
+    /* reorder only down to the lowest odd level */
+    minLevel|=1;
+
+    /* loop maxLevel..minLevel */
+    do {
+        start=0;
+
+        /* loop for all sequences of levels to reorder at the current maxLevel */
+        for(;;) {
+            /* look for a sequence of levels that are all at >=maxLevel */
+            /* look for the first index of such a sequence */
+            while(start<length && levels[start]<maxLevel) {
+                ++start;
+            }
+            if(start>=length) {
+                break;  /* no more such runs */
+            }
+
+            /* look for the limit of such a sequence (the index behind it) */
+            for(limit=start; ++limit<length && levels[limit]>=maxLevel;) {}
+
+            /*
+             * Swap the entire interval of indexes from start to limit-1.
+             * We don't need to swap the levels for the purpose of this
+             * algorithm: the sequence of levels that we look at does not
+             * move anyway.
+             */
+            end=limit-1;
+            while(start<end) {
+                temp=indexMap[start];
+                indexMap[start]=indexMap[end];
+                indexMap[end]=temp;
+
+                ++start;
+                --end;
+            }
+
+            if(limit==length) {
+                break;  /* no more such sequences */
+            } else {
+                start=limit+1;
+            }
+        }
+    } while(--maxLevel>=minLevel);
+}
+
+/* API functions for logical<->visual mapping ------------------------------- */
+
+U_CAPI int32_t U_EXPORT2
+ubidi_getVisualIndex(UBiDi *pBiDi, int32_t logicalIndex, UErrorCode *pErrorCode) {
+    int32_t visualIndex=UBIDI_MAP_NOWHERE;
+    RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrorCode, -1);
+    RETURN_IF_NOT_VALID_PARA_OR_LINE(pBiDi, *pErrorCode, -1);
+    RETURN_IF_BAD_RANGE(logicalIndex, 0, pBiDi->length, *pErrorCode, -1);
+
+    /* we can do the trivial cases without the runs array */
+    switch(pBiDi->direction) {
+    case UBIDI_LTR:
+        visualIndex=logicalIndex;
+        break;
+    case UBIDI_RTL:
+        visualIndex=pBiDi->length-logicalIndex-1;
+        break;
+    default:
+        if(!ubidi_getRuns(pBiDi, pErrorCode)) {
+            *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+            return -1;
+        } else {
+            Run *runs=pBiDi->runs;
+            int32_t i, visualStart=0, offset, length;
+
+            /* linear search for the run, search on the visual runs */
+            for(i=0; i<pBiDi->runCount; ++i) {
+                length=runs[i].visualLimit-visualStart;
+                offset=logicalIndex-GET_INDEX(runs[i].logicalStart);
+                if(offset>=0 && offset<length) {
+                    if(IS_EVEN_RUN(runs[i].logicalStart)) {
+                        /* LTR */
+                        visualIndex=visualStart+offset;
+                    } else {
+                        /* RTL */
+                        visualIndex=visualStart+length-offset-1;
+                    }
+                    break;          /* exit for loop */
+                }
+                visualStart+=length;
+            }
+            if(i>=pBiDi->runCount) {
+                return UBIDI_MAP_NOWHERE;
+            }
+        }
+    }
+
+    if(pBiDi->insertPoints.size>0) {
+        /* add the number of added marks until the calculated visual index */
+        Run *runs=pBiDi->runs;
+        int32_t i, length, insertRemove;
+        int32_t visualStart=0, markFound=0;
+        for(i=0; ; i++, visualStart+=length) {
+            length=runs[i].visualLimit-visualStart;
+            insertRemove=runs[i].insertRemove;
+            if(insertRemove & (LRM_BEFORE|RLM_BEFORE)) {
+                markFound++;
+            }
+            /* is it the run containing the visual index? */
+            if(visualIndex<runs[i].visualLimit) {
+                return visualIndex+markFound;
+            }
+            if(insertRemove & (LRM_AFTER|RLM_AFTER)) {
+                markFound++;
+            }
+        }
+    }
+    else if(pBiDi->controlCount>0) {
+        /* subtract the number of controls until the calculated visual index */
+        Run *runs=pBiDi->runs;
+        int32_t i, j, start, limit, length, insertRemove;
+        int32_t visualStart=0, controlFound=0;
+        UChar uchar=pBiDi->text[logicalIndex];
+        /* is the logical index pointing to a control ? */
+        if(IS_BIDI_CONTROL_CHAR(uchar)) {
+            return UBIDI_MAP_NOWHERE;
+        }
+        /* loop on runs */
+        for(i=0; ; i++, visualStart+=length) {
+            length=runs[i].visualLimit-visualStart;
+            insertRemove=runs[i].insertRemove;
+            /* calculated visual index is beyond this run? */
+            if(visualIndex>=runs[i].visualLimit) {
+                controlFound-=insertRemove;
+                continue;
+            }
+            /* calculated visual index must be within current run */
+            if(insertRemove==0) {
+                return visualIndex-controlFound;
+            }
+            if(IS_EVEN_RUN(runs[i].logicalStart)) {
+                /* LTR: check from run start to logical index */
+                start=runs[i].logicalStart;
+                limit=logicalIndex;
+            } else {
+                /* RTL: check from logical index to run end */
+                start=logicalIndex+1;
+                limit=GET_INDEX(runs[i].logicalStart)+length;
+            }
+            for(j=start; j<limit; j++) {
+                uchar=pBiDi->text[j];
+                if(IS_BIDI_CONTROL_CHAR(uchar)) {
+                    controlFound++;
+                }
+            }
+            return visualIndex-controlFound;
+        }
+    }
+
+    return visualIndex;
+}
+
+U_CAPI int32_t U_EXPORT2
+ubidi_getLogicalIndex(UBiDi *pBiDi, int32_t visualIndex, UErrorCode *pErrorCode) {
+    Run *runs;
+    int32_t i, runCount, start;
+    RETURN_IF_NULL_OR_FAILING_ERRCODE(pErrorCode, -1);
+    RETURN_IF_NOT_VALID_PARA_OR_LINE(pBiDi, *pErrorCode, -1);
+    RETURN_IF_BAD_RANGE(visualIndex, 0, pBiDi->resultLength, *pErrorCode, -1);
+    /* we can do the trivial cases without the runs array */
+    if(pBiDi->insertPoints.size==0 && pBiDi->controlCount==0) {
+        if(pBiDi->direction==UBIDI_LTR) {
+            return visualIndex;
+        }
+        else if(pBiDi->direction==UBIDI_RTL) {
+            return pBiDi->length-visualIndex-1;
+        }
+    }
+    if(!ubidi_getRuns(pBiDi, pErrorCode)) {
+        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+        return -1;
+    }
+
+    runs=pBiDi->runs;
+    runCount=pBiDi->runCount;
+    if(pBiDi->insertPoints.size>0) {
+        /* handle inserted LRM/RLM */
+        int32_t markFound=0, insertRemove;
+        int32_t visualStart=0, length;
+        runs=pBiDi->runs;
+        /* subtract number of marks until visual index */
+        for(i=0; ; i++, visualStart+=length) {
+            length=runs[i].visualLimit-visualStart;
+            insertRemove=runs[i].insertRemove;
+            if(insertRemove&(LRM_BEFORE|RLM_BEFORE)) {
+                if(visualIndex<=(visualStart+markFound)) {
+                    return UBIDI_MAP_NOWHERE;
+                }
+                markFound++;
+            }
+            /* is adjusted visual index within this run? */
+            if(visualIndex<(runs[i].visualLimit+markFound)) {
+                visualIndex-=markFound;
+                break;
+            }
+            if(insertRemove&(LRM_AFTER|RLM_AFTER)) {
+                if(visualIndex==(visualStart+length+markFound)) {
+                    return UBIDI_MAP_NOWHERE;
+                }
+                markFound++;
+            }
+        }
+    }
+    else if(pBiDi->controlCount>0) {
+        /* handle removed BiDi control characters */
+        int32_t controlFound=0, insertRemove, length;
+        int32_t logicalStart, logicalEnd, visualStart=0, j, k;
+        UChar uchar;
+        UBool evenRun;
+        /* add number of controls until visual index */
+        for(i=0; ; i++, visualStart+=length) {
+            length=runs[i].visualLimit-visualStart;
+            insertRemove=runs[i].insertRemove;
+            /* is adjusted visual index beyond current run? */
+            if(visualIndex>=(runs[i].visualLimit-controlFound+insertRemove)) {
+                controlFound-=insertRemove;
+                continue;
+            }
+            /* adjusted visual index is within current run */
+            if(insertRemove==0) {
+                visualIndex+=controlFound;
+                break;
+            }
+            /* count non-control chars until visualIndex */
+            logicalStart=runs[i].logicalStart;
+            evenRun=IS_EVEN_RUN(logicalStart);
+            REMOVE_ODD_BIT(logicalStart);
+            logicalEnd=logicalStart+length-1;
+            for(j=0; j<length; j++) {
+                k= evenRun ? logicalStart+j : logicalEnd-j;
+                uchar=pBiDi->text[k];
+                if(IS_BIDI_CONTROL_CHAR(uchar)) {
+                    controlFound++;
+                }
+                if((visualIndex+controlFound)==(visualStart+j)) {
+                    break;
+                }
+            }
+            visualIndex+=controlFound;
+            break;
+        }
+    }
+    /* handle all cases */
+    if(runCount<=10) {
+        /* linear search for the run */
+        for(i=0; visualIndex>=runs[i].visualLimit; ++i) {}
+    } else {
+        /* binary search for the run */
+        int32_t begin=0, limit=runCount;
+
+        /* the middle if() is guaranteed to find the run, we don't need a loop limit */
+        for(;;) {
+            i=(begin+limit)/2;
+            if(visualIndex>=runs[i].visualLimit) {
+                begin=i+1;
+            } else if(i==0 || visualIndex>=runs[i-1].visualLimit) {
+                break;
+            } else {
+                limit=i;
+            }
+        }
+    }
+
+    start=runs[i].logicalStart;
+    if(IS_EVEN_RUN(start)) {
+        /* LTR */
+        /* the offset in runs[i] is visualIndex-runs[i-1].visualLimit */
+        if(i>0) {
+            visualIndex-=runs[i-1].visualLimit;
+        }
+        return start+visualIndex;
+    } else {
+        /* RTL */
+        return GET_INDEX(start)+runs[i].visualLimit-visualIndex-1;
+    }
+}
+
+U_CAPI void U_EXPORT2
+ubidi_getLogicalMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode) {
+    RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrorCode);
+    /* ubidi_countRuns() checks for VALID_PARA_OR_LINE */
+    ubidi_countRuns(pBiDi, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        /* no op */
+    } else if(indexMap==NULL) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+    } else {
+        /* fill a logical-to-visual index map using the runs[] */
+        int32_t visualStart, visualLimit, i, j, k;
+        int32_t logicalStart, logicalLimit;
+        Run *runs=pBiDi->runs;
+        if (pBiDi->length<=0) {
+            return;
+        }
+        if (pBiDi->length>pBiDi->resultLength) {
+            uprv_memset(indexMap, 0xFF, pBiDi->length*sizeof(int32_t));
+        }
+
+        visualStart=0;
+        for(j=0; j<pBiDi->runCount; ++j) {
+            logicalStart=GET_INDEX(runs[j].logicalStart);
+            visualLimit=runs[j].visualLimit;
+            if(IS_EVEN_RUN(runs[j].logicalStart)) {
+                do { /* LTR */
+                    indexMap[logicalStart++]=visualStart++;
+                } while(visualStart<visualLimit);
+            } else {
+                logicalStart+=visualLimit-visualStart;  /* logicalLimit */
+                do { /* RTL */
+                    indexMap[--logicalStart]=visualStart++;
+                } while(visualStart<visualLimit);
+            }
+            /* visualStart==visualLimit; */
+        }
+
+        if(pBiDi->insertPoints.size>0) {
+            int32_t markFound=0, runCount=pBiDi->runCount;
+            int32_t length, insertRemove;
+            visualStart=0;
+            /* add number of marks found until each index */
+            for(i=0; i<runCount; i++, visualStart+=length) {
+                length=runs[i].visualLimit-visualStart;
+                insertRemove=runs[i].insertRemove;
+                if(insertRemove&(LRM_BEFORE|RLM_BEFORE)) {
+                    markFound++;
+                }
+                if(markFound>0) {
+                    logicalStart=GET_INDEX(runs[i].logicalStart);
+                    logicalLimit=logicalStart+length;
+                    for(j=logicalStart; j<logicalLimit; j++) {
+                        indexMap[j]+=markFound;
+                    }
+                }
+                if(insertRemove&(LRM_AFTER|RLM_AFTER)) {
+                    markFound++;
+                }
+            }
+        }
+        else if(pBiDi->controlCount>0) {
+            int32_t controlFound=0, runCount=pBiDi->runCount;
+            int32_t length, insertRemove;
+            UBool evenRun;
+            UChar uchar;
+            visualStart=0;
+            /* subtract number of controls found until each index */
+            for(i=0; i<runCount; i++, visualStart+=length) {
+                length=runs[i].visualLimit-visualStart;
+                insertRemove=runs[i].insertRemove;
+                /* no control found within previous runs nor within this run */
+                if((controlFound-insertRemove)==0) {
+                    continue;
+                }
+                logicalStart=runs[i].logicalStart;
+                evenRun=IS_EVEN_RUN(logicalStart);
+                REMOVE_ODD_BIT(logicalStart);
+                logicalLimit=logicalStart+length;
+                /* if no control within this run */
+                if(insertRemove==0) {
+                    for(j=logicalStart; j<logicalLimit; j++) {
+                        indexMap[j]-=controlFound;
+                    }
+                    continue;
+                }
+                for(j=0; j<length; j++) {
+                    k= evenRun ? logicalStart+j : logicalLimit-j-1;
+                    uchar=pBiDi->text[k];
+                    if(IS_BIDI_CONTROL_CHAR(uchar)) {
+                        controlFound++;
+                        indexMap[k]=UBIDI_MAP_NOWHERE;
+                        continue;
+                    }
+                    indexMap[k]-=controlFound;
+                }
+            }
+        }
+    }
+}
+
+U_CAPI void U_EXPORT2
+ubidi_getVisualMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode) {
+    RETURN_VOID_IF_NULL_OR_FAILING_ERRCODE(pErrorCode);
+    if(indexMap==NULL) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    /* ubidi_countRuns() checks for VALID_PARA_OR_LINE */
+    ubidi_countRuns(pBiDi, pErrorCode);
+    if(U_SUCCESS(*pErrorCode)) {
+        /* fill a visual-to-logical index map using the runs[] */
+        Run *runs=pBiDi->runs, *runsLimit=runs+pBiDi->runCount;
+        int32_t logicalStart, visualStart, visualLimit, *pi=indexMap;
+
+        if (pBiDi->resultLength<=0) {
+            return;
+        }
+        visualStart=0;
+        for(; runs<runsLimit; ++runs) {
+            logicalStart=runs->logicalStart;
+            visualLimit=runs->visualLimit;
+            if(IS_EVEN_RUN(logicalStart)) {
+                do { /* LTR */
+                    *pi++ = logicalStart++;
+                } while(++visualStart<visualLimit);
+            } else {
+                REMOVE_ODD_BIT(logicalStart);
+                logicalStart+=visualLimit-visualStart;  /* logicalLimit */
+                do { /* RTL */
+                    *pi++ = --logicalStart;
+                } while(++visualStart<visualLimit);
+            }
+            /* visualStart==visualLimit; */
+        }
+
+        if(pBiDi->insertPoints.size>0) {
+            int32_t markFound=0, runCount=pBiDi->runCount;
+            int32_t insertRemove, i, j, k;
+            runs=pBiDi->runs;
+            /* count all inserted marks */
+            for(i=0; i<runCount; i++) {
+                insertRemove=runs[i].insertRemove;
+                if(insertRemove&(LRM_BEFORE|RLM_BEFORE)) {
+                    markFound++;
+                }
+                if(insertRemove&(LRM_AFTER|RLM_AFTER)) {
+                    markFound++;
+                }
+            }
+            /* move back indexes by number of preceding marks */
+            k=pBiDi->resultLength;
+            for(i=runCount-1; i>=0 && markFound>0; i--) {
+                insertRemove=runs[i].insertRemove;
+                if(insertRemove&(LRM_AFTER|RLM_AFTER)) {
+                    indexMap[--k]= UBIDI_MAP_NOWHERE;
+                    markFound--;
+                }
+                visualStart= i>0 ? runs[i-1].visualLimit : 0;
+                for(j=runs[i].visualLimit-1; j>=visualStart && markFound>0; j--) {
+                    indexMap[--k]=indexMap[j];
+                }
+                if(insertRemove&(LRM_BEFORE|RLM_BEFORE)) {
+                    indexMap[--k]= UBIDI_MAP_NOWHERE;
+                    markFound--;
+                }
+            }
+        }
+        else if(pBiDi->controlCount>0) {
+            int32_t runCount=pBiDi->runCount, logicalEnd;
+            int32_t insertRemove, length, i, j, k, m;
+            UChar uchar;
+            UBool evenRun;
+            runs=pBiDi->runs;
+            visualStart=0;
+            /* move forward indexes by number of preceding controls */
+            k=0;
+            for(i=0; i<runCount; i++, visualStart+=length) {
+                length=runs[i].visualLimit-visualStart;
+                insertRemove=runs[i].insertRemove;
+                /* if no control found yet, nothing to do in this run */
+                if((insertRemove==0)&&(k==visualStart)) {
+                    k+=length;
+                    continue;
+                }
+                /* if no control in this run */
+                if(insertRemove==0) {
+                    visualLimit=runs[i].visualLimit;
+                    for(j=visualStart; j<visualLimit; j++) {
+                        indexMap[k++]=indexMap[j];
+                    }
+                    continue;
+                }
+                logicalStart=runs[i].logicalStart;
+                evenRun=IS_EVEN_RUN(logicalStart);
+                REMOVE_ODD_BIT(logicalStart);
+                logicalEnd=logicalStart+length-1;
+                for(j=0; j<length; j++) {
+                    m= evenRun ? logicalStart+j : logicalEnd-j;
+                    uchar=pBiDi->text[m];
+                    if(!IS_BIDI_CONTROL_CHAR(uchar)) {
+                        indexMap[k++]=m;
+                    }
+                }
+            }
+        }
+    }
+}
+
+U_CAPI void U_EXPORT2
+ubidi_invertMap(const int32_t *srcMap, int32_t *destMap, int32_t length) {
+    if(srcMap!=NULL && destMap!=NULL && length>0) {
+        const int32_t *pi;
+        int32_t destLength=-1, count=0;
+        /* find highest value and count positive indexes in srcMap */
+        pi=srcMap+length;
+        while(pi>srcMap) {
+            if(*--pi>destLength) {
+                destLength=*pi;
+            }
+            if(*pi>=0) {
+                count++;
+            }
+        }
+        destLength++;           /* add 1 for origin 0 */
+        if(count<destLength) {
+            /* we must fill unmatched destMap entries with -1 */
+            uprv_memset(destMap, 0xFF, destLength*sizeof(int32_t));
+        }
+        pi=srcMap+length;
+        while(length>0) {
+            if(*--pi>=0) {
+                destMap[*pi]=--length;
+            } else {
+                --length;
+            }
+        }
+    }
+}
diff --git a/icu/source/common/ubidiwrt.c b/icu/source/common/ubidiwrt.c
new file mode 100644
index 0000000..34b1371
--- /dev/null
+++ b/icu/source/common/ubidiwrt.c
@@ -0,0 +1,630 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 2000-2007, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*   file name:  ubidiwrt.c
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 1999aug06
+*   created by: Markus W. Scherer, updated by Matitiahu Allouche
+*
+* This file contains implementations for BiDi functions that use
+* the core algorithm and core API to write reordered text.
+*/
+
+/* set import/export definitions */
+#ifndef U_COMMON_IMPLEMENTATION
+#   define U_COMMON_IMPLEMENTATION
+#endif
+
+#include "unicode/utypes.h"
+#include "unicode/ustring.h"
+#include "unicode/uchar.h"
+#include "unicode/ubidi.h"
+#include "cmemory.h"
+#include "ustr_imp.h"
+#include "ubidiimp.h"
+
+/*
+ * The function implementations in this file are designed
+ * for UTF-16 and UTF-32, not for UTF-8.
+ *
+ * Assumptions that are not true for UTF-8:
+ * - Any code point always needs the same number of code units
+ *   ("minimum-length-problem" of UTF-8)
+ * - The BiDi control characters need only one code unit each
+ *
+ * Further assumptions for all UTFs:
+ * - u_charMirror(c) needs the same number of code units as c
+ */
+#if UTF_SIZE==8
+# error reimplement ubidi_writeReordered() for UTF-8, see comment above
+#endif
+
+#define IS_COMBINING(type) ((1UL<<(type))&(1UL<<U_NON_SPACING_MARK|1UL<<U_COMBINING_SPACING_MARK|1UL<<U_ENCLOSING_MARK))
+
+/*
+ * When we have UBIDI_OUTPUT_REVERSE set on ubidi_writeReordered(), then we
+ * semantically write RTL runs in reverse and later reverse them again.
+ * Instead, we actually write them in forward order to begin with.
+ * However, if the RTL run was to be mirrored, we need to mirror here now
+ * since the implicit second reversal must not do it.
+ * It looks strange to do mirroring in LTR output, but it is only because
+ * we are writing RTL output in reverse.
+ */
+static int32_t
+doWriteForward(const UChar *src, int32_t srcLength,
+               UChar *dest, int32_t destSize,
+               uint16_t options,
+               UErrorCode *pErrorCode) {
+    /* optimize for several combinations of options */
+    switch(options&(UBIDI_REMOVE_BIDI_CONTROLS|UBIDI_DO_MIRRORING)) {
+    case 0: {
+        /* simply copy the LTR run to the destination */
+        int32_t length=srcLength;
+        if(destSize<length) {
+            *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
+            return srcLength;
+        }
+        do {
+            *dest++=*src++;
+        } while(--length>0);
+        return srcLength;
+    }
+    case UBIDI_DO_MIRRORING: {
+        /* do mirroring */
+        int32_t i=0, j=0;
+        UChar32 c;
+
+        if(destSize<srcLength) {
+            *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
+            return srcLength;
+        }
+        do {
+            UTF_NEXT_CHAR(src, i, srcLength, c);
+            c=u_charMirror(c);
+            UTF_APPEND_CHAR_UNSAFE(dest, j, c);
+        } while(i<srcLength);
+        return srcLength;
+    }
+    case UBIDI_REMOVE_BIDI_CONTROLS: {
+        /* copy the LTR run and remove any BiDi control characters */
+        int32_t remaining=destSize;
+        UChar c;
+        do {
+            c=*src++;
+            if(!IS_BIDI_CONTROL_CHAR(c)) {
+                if(--remaining<0) {
+                    *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
+
+                    /* preflight the length */
+                    while(--srcLength>0) {
+                        c=*src++;
+                        if(!IS_BIDI_CONTROL_CHAR(c)) {
+                            --remaining;
+                        }
+                    }
+                    return destSize-remaining;
+                }
+                *dest++=c;
+            }
+        } while(--srcLength>0);
+        return destSize-remaining;
+    }
+    default: {
+        /* remove BiDi control characters and do mirroring */
+        int32_t remaining=destSize;
+        int32_t i, j=0;
+        UChar32 c;
+        do {
+            i=0;
+            UTF_NEXT_CHAR(src, i, srcLength, c);
+            src+=i;
+            srcLength-=i;
+            if(!IS_BIDI_CONTROL_CHAR(c)) {
+                remaining-=i;
+                if(remaining<0) {
+                    *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
+
+                    /* preflight the length */
+                    while(srcLength>0) {
+                        c=*src++;
+                        if(!IS_BIDI_CONTROL_CHAR(c)) {
+                            --remaining;
+                        }
+                        --srcLength;
+                    }
+                    return destSize-remaining;
+                }
+                c=u_charMirror(c);
+                UTF_APPEND_CHAR_UNSAFE(dest, j, c);
+            }
+        } while(srcLength>0);
+        return j;
+    }
+    } /* end of switch */
+}
+
+static int32_t
+doWriteReverse(const UChar *src, int32_t srcLength,
+               UChar *dest, int32_t destSize,
+               uint16_t options,
+               UErrorCode *pErrorCode) {
+    /*
+     * RTL run -
+     *
+     * RTL runs need to be copied to the destination in reverse order
+     * of code points, not code units, to keep Unicode characters intact.
+     *
+     * The general strategy for this is to read the source text
+     * in backward order, collect all code units for a code point
+     * (and optionally following combining characters, see below),
+     * and copy all these code units in ascending order
+     * to the destination for this run.
+     *
+     * Several options request whether combining characters
+     * should be kept after their base characters,
+     * whether BiDi control characters should be removed, and
+     * whether characters should be replaced by their mirror-image
+     * equivalent Unicode characters.
+     */
+    int32_t i, j;
+    UChar32 c;
+
+    /* optimize for several combinations of options */
+    switch(options&(UBIDI_REMOVE_BIDI_CONTROLS|UBIDI_DO_MIRRORING|UBIDI_KEEP_BASE_COMBINING)) {
+    case 0:
+        /*
+         * With none of the "complicated" options set, the destination
+         * run will have the same length as the source run,
+         * and there is no mirroring and no keeping combining characters
+         * with their base characters.
+         */
+        if(destSize<srcLength) {
+            *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
+            return srcLength;
+        }
+        destSize=srcLength;
+
+        /* preserve character integrity */
+        do {
+            /* i is always after the last code unit known to need to be kept in this segment */
+            i=srcLength;
+
+            /* collect code units for one base character */
+            UTF_BACK_1(src, 0, srcLength);
+
+            /* copy this base character */
+            j=srcLength;
+            do {
+                *dest++=src[j++];
+            } while(j<i);
+        } while(srcLength>0);
+        break;
+    case UBIDI_KEEP_BASE_COMBINING:
+        /*
+         * Here, too, the destination
+         * run will have the same length as the source run,
+         * and there is no mirroring.
+         * We do need to keep combining characters with their base characters.
+         */
+        if(destSize<srcLength) {
+            *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
+            return srcLength;
+        }
+        destSize=srcLength;
+
+        /* preserve character integrity */
+        do {
+            /* i is always after the last code unit known to need to be kept in this segment */
+            i=srcLength;
+
+            /* collect code units and modifier letters for one base character */
+            do {
+                UTF_PREV_CHAR(src, 0, srcLength, c);
+            } while(srcLength>0 && IS_COMBINING(u_charType(c)));
+
+            /* copy this "user character" */
+            j=srcLength;
+            do {
+                *dest++=src[j++];
+            } while(j<i);
+        } while(srcLength>0);
+        break;
+    default:
+        /*
+         * With several "complicated" options set, this is the most
+         * general and the slowest copying of an RTL run.
+         * We will do mirroring, remove BiDi controls, and
+         * keep combining characters with their base characters
+         * as requested.
+         */
+        if(!(options&UBIDI_REMOVE_BIDI_CONTROLS)) {
+            i=srcLength;
+        } else {
+            /* we need to find out the destination length of the run,
+               which will not include the BiDi control characters */
+            int32_t length=srcLength;
+            UChar ch;
+
+            i=0;
+            do {
+                ch=*src++;
+                if(!IS_BIDI_CONTROL_CHAR(ch)) {
+                    ++i;
+                }
+            } while(--length>0);
+            src-=srcLength;
+        }
+
+        if(destSize<i) {
+            *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
+            return i;
+        }
+        destSize=i;
+
+        /* preserve character integrity */
+        do {
+            /* i is always after the last code unit known to need to be kept in this segment */
+            i=srcLength;
+
+            /* collect code units for one base character */
+            UTF_PREV_CHAR(src, 0, srcLength, c);
+            if(options&UBIDI_KEEP_BASE_COMBINING) {
+                /* collect modifier letters for this base character */
+                while(srcLength>0 && IS_COMBINING(u_charType(c))) {
+                    UTF_PREV_CHAR(src, 0, srcLength, c);
+                }
+            }
+
+            if(options&UBIDI_REMOVE_BIDI_CONTROLS && IS_BIDI_CONTROL_CHAR(c)) {
+                /* do not copy this BiDi control character */
+                continue;
+            }
+
+            /* copy this "user character" */
+            j=srcLength;
+            if(options&UBIDI_DO_MIRRORING) {
+                /* mirror only the base character */
+                int32_t k=0;
+                c=u_charMirror(c);
+                UTF_APPEND_CHAR_UNSAFE(dest, k, c);
+                dest+=k;
+                j+=k;
+            }
+            while(j<i) {
+                *dest++=src[j++];
+            }
+        } while(srcLength>0);
+        break;
+    } /* end of switch */
+
+    return destSize;
+}
+
+U_CAPI int32_t U_EXPORT2
+ubidi_writeReverse(const UChar *src, int32_t srcLength,
+                   UChar *dest, int32_t destSize,
+                   uint16_t options,
+                   UErrorCode *pErrorCode) {
+    int32_t destLength;
+
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    /* more error checking */
+    if( src==NULL || srcLength<-1 ||
+        destSize<0 || (destSize>0 && dest==NULL))
+    {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    /* do input and output overlap? */
+    if( dest!=NULL &&
+        ((src>=dest && src<dest+destSize) ||
+         (dest>=src && dest<src+srcLength)))
+    {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    if(srcLength==-1) {
+        srcLength=u_strlen(src);
+    }
+    if(srcLength>0) {
+        destLength=doWriteReverse(src, srcLength, dest, destSize, options, pErrorCode);
+    } else {
+        /* nothing to do */
+        destLength=0;
+    }
+
+    return u_terminateUChars(dest, destSize, destLength, pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+ubidi_writeReordered(UBiDi *pBiDi,
+                     UChar *dest, int32_t destSize,
+                     uint16_t options,
+                     UErrorCode *pErrorCode) {
+    const UChar *text;
+    UChar *saveDest;
+    int32_t length, destCapacity;
+    int32_t run, runCount, logicalStart, runLength;
+
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    /* more error checking */
+    if( pBiDi==NULL ||
+        (text=pBiDi->text)==NULL || (length=pBiDi->length)<0 ||
+        destSize<0 || (destSize>0 && dest==NULL))
+    {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    /* do input and output overlap? */
+    if( dest!=NULL &&
+        ((text>=dest && text<dest+destSize) ||
+         (dest>=text && dest<text+pBiDi->originalLength)))
+    {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    if(length==0) {
+        /* nothing to do */
+        return u_terminateUChars(dest, destSize, 0, pErrorCode);
+    }
+
+    runCount=ubidi_countRuns(pBiDi, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    /* destSize shrinks, later destination length=destCapacity-destSize */
+    saveDest=dest;
+    destCapacity=destSize;
+
+    /*
+     * Option "insert marks" implies UBIDI_INSERT_LRM_FOR_NUMERIC if the
+     * reordering mode (checked below) is appropriate.
+     */
+    if(pBiDi->reorderingOptions & UBIDI_OPTION_INSERT_MARKS) {
+        options|=UBIDI_INSERT_LRM_FOR_NUMERIC;
+        options&=~UBIDI_REMOVE_BIDI_CONTROLS;
+    }
+    /*
+     * Option "remove controls" implies UBIDI_REMOVE_BIDI_CONTROLS
+     * and cancels UBIDI_INSERT_LRM_FOR_NUMERIC.
+     */
+    if(pBiDi->reorderingOptions & UBIDI_OPTION_REMOVE_CONTROLS) {
+        options|=UBIDI_REMOVE_BIDI_CONTROLS;
+        options&=~UBIDI_INSERT_LRM_FOR_NUMERIC;
+    }
+    /*
+     * If we do not perform the "inverse BiDi" algorithm, then we
+     * don't need to insert any LRMs, and don't need to test for it.
+     */
+    if((pBiDi->reorderingMode != UBIDI_REORDER_INVERSE_NUMBERS_AS_L) &&
+       (pBiDi->reorderingMode != UBIDI_REORDER_INVERSE_LIKE_DIRECT)  &&
+       (pBiDi->reorderingMode != UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL) &&
+       (pBiDi->reorderingMode != UBIDI_REORDER_RUNS_ONLY)) {
+        options&=~UBIDI_INSERT_LRM_FOR_NUMERIC;
+    }
+    /*
+     * Iterate through all visual runs and copy the run text segments to
+     * the destination, according to the options.
+     *
+     * The tests for where to insert LRMs ignore the fact that there may be
+     * BN codes or non-BMP code points at the beginning and end of a run;
+     * they may insert LRMs unnecessarily but the tests are faster this way
+     * (this would have to be improved for UTF-8).
+     *
+     * Note that the only errors that are set by doWriteXY() are buffer overflow
+     * errors. Ignore them until the end, and continue for preflighting.
+     */
+    if(!(options&UBIDI_OUTPUT_REVERSE)) {
+        /* forward output */
+        if(!(options&UBIDI_INSERT_LRM_FOR_NUMERIC)) {
+            /* do not insert BiDi controls */
+            for(run=0; run<runCount; ++run) {
+                if(UBIDI_LTR==ubidi_getVisualRun(pBiDi, run, &logicalStart, &runLength)) {
+                    runLength=doWriteForward(text+logicalStart, runLength,
+                                             dest, destSize,
+                                             (uint16_t)(options&~UBIDI_DO_MIRRORING), pErrorCode);
+                } else {
+                    runLength=doWriteReverse(text+logicalStart, runLength,
+                                             dest, destSize,
+                                             options, pErrorCode);
+                }
+                dest+=runLength;
+                destSize-=runLength;
+            }
+        } else {
+            /* insert BiDi controls for "inverse BiDi" */
+            const DirProp *dirProps=pBiDi->dirProps;
+            const UChar *src;
+            UChar uc;
+            UBiDiDirection dir;
+            int32_t markFlag;
+
+            for(run=0; run<runCount; ++run) {
+                dir=ubidi_getVisualRun(pBiDi, run, &logicalStart, &runLength);
+                src=text+logicalStart;
+                /* check if something relevant in insertPoints */
+                markFlag=pBiDi->runs[run].insertRemove;
+                if(markFlag<0) {        /* BiDi controls count */
+                    markFlag=0;
+                }
+
+                if(UBIDI_LTR==dir) {
+                    if((pBiDi->isInverse) &&
+                       (/*run>0 &&*/ dirProps[logicalStart]!=L)) {
+                        markFlag |= LRM_BEFORE;
+                    }
+                    if (markFlag & LRM_BEFORE) {
+                        uc=LRM_CHAR;
+                    }
+                    else if (markFlag & RLM_BEFORE) {
+                        uc=RLM_CHAR;
+                    }
+                    else  uc=0;
+                    if(uc) {
+                        if(destSize>0) {
+                            *dest++=uc;
+                        }
+                        --destSize;
+                    }
+
+                    runLength=doWriteForward(src, runLength,
+                                             dest, destSize,
+                                             (uint16_t)(options&~UBIDI_DO_MIRRORING), pErrorCode);
+                    dest+=runLength;
+                    destSize-=runLength;
+
+                    if((pBiDi->isInverse) &&
+                       (/*run<runCount-1 &&*/ dirProps[logicalStart+runLength-1]!=L)) {
+                        markFlag |= LRM_AFTER;
+                    }
+                    if (markFlag & LRM_AFTER) {
+                        uc=LRM_CHAR;
+                    }
+                    else if (markFlag & RLM_AFTER) {
+                        uc=RLM_CHAR;
+                    }
+                    else  uc=0;
+                    if(uc) {
+                        if(destSize>0) {
+                            *dest++=uc;
+                        }
+                        --destSize;
+                    }
+                } else {                /* RTL run */
+                    if((pBiDi->isInverse) &&
+                       (/*run>0 &&*/ !(MASK_R_AL&DIRPROP_FLAG(dirProps[logicalStart+runLength-1])))) {
+                        markFlag |= RLM_BEFORE;
+                    }
+                    if (markFlag & LRM_BEFORE) {
+                        uc=LRM_CHAR;
+                    }
+                    else if (markFlag & RLM_BEFORE) {
+                        uc=RLM_CHAR;
+                    }
+                    else  uc=0;
+                    if(uc) {
+                        if(destSize>0) {
+                            *dest++=uc;
+                        }
+                        --destSize;
+                    }
+
+                    runLength=doWriteReverse(src, runLength,
+                                             dest, destSize,
+                                             options, pErrorCode);
+                    dest+=runLength;
+                    destSize-=runLength;
+
+                    if((pBiDi->isInverse) &&
+                       (/*run<runCount-1 &&*/ !(MASK_R_AL&DIRPROP_FLAG(dirProps[logicalStart])))) {
+                        markFlag |= RLM_AFTER;
+                    }
+                    if (markFlag & LRM_AFTER) {
+                        uc=LRM_CHAR;
+                    }
+                    else if (markFlag & RLM_AFTER) {
+                        uc=RLM_CHAR;
+                    }
+                    else  uc=0;
+                    if(uc) {
+                        if(destSize>0) {
+                            *dest++=uc;
+                        }
+                        --destSize;
+                    }
+                }
+            }
+        }
+    } else {
+        /* reverse output */
+        if(!(options&UBIDI_INSERT_LRM_FOR_NUMERIC)) {
+            /* do not insert BiDi controls */
+            for(run=runCount; --run>=0;) {
+                if(UBIDI_LTR==ubidi_getVisualRun(pBiDi, run, &logicalStart, &runLength)) {
+                    runLength=doWriteReverse(text+logicalStart, runLength,
+                                             dest, destSize,
+                                             (uint16_t)(options&~UBIDI_DO_MIRRORING), pErrorCode);
+                } else {
+                    runLength=doWriteForward(text+logicalStart, runLength,
+                                             dest, destSize,
+                                             options, pErrorCode);
+                }
+                dest+=runLength;
+                destSize-=runLength;
+            }
+        } else {
+            /* insert BiDi controls for "inverse BiDi" */
+            const DirProp *dirProps=pBiDi->dirProps;
+            const UChar *src;
+            UBiDiDirection dir;
+
+            for(run=runCount; --run>=0;) {
+                /* reverse output */
+                dir=ubidi_getVisualRun(pBiDi, run, &logicalStart, &runLength);
+                src=text+logicalStart;
+
+                if(UBIDI_LTR==dir) {
+                    if(/*run<runCount-1 &&*/ dirProps[logicalStart+runLength-1]!=L) {
+                        if(destSize>0) {
+                            *dest++=LRM_CHAR;
+                        }
+                        --destSize;
+                    }
+
+                    runLength=doWriteReverse(src, runLength,
+                                             dest, destSize,
+                                             (uint16_t)(options&~UBIDI_DO_MIRRORING), pErrorCode);
+                    dest+=runLength;
+                    destSize-=runLength;
+
+                    if(/*run>0 &&*/ dirProps[logicalStart]!=L) {
+                        if(destSize>0) {
+                            *dest++=LRM_CHAR;
+                        }
+                        --destSize;
+                    }
+                } else {
+                    if(/*run<runCount-1 &&*/ !(MASK_R_AL&DIRPROP_FLAG(dirProps[logicalStart]))) {
+                        if(destSize>0) {
+                            *dest++=RLM_CHAR;
+                        }
+                        --destSize;
+                    }
+
+                    runLength=doWriteForward(src, runLength,
+                                             dest, destSize,
+                                             options, pErrorCode);
+                    dest+=runLength;
+                    destSize-=runLength;
+
+                    if(/*run>0 &&*/ !(MASK_R_AL&DIRPROP_FLAG(dirProps[logicalStart+runLength-1]))) {
+                        if(destSize>0) {
+                            *dest++=RLM_CHAR;
+                        }
+                        --destSize;
+                    }
+                }
+            }
+        }
+    }
+
+    return u_terminateUChars(saveDest, destCapacity, destCapacity-destSize, pErrorCode);
+}
diff --git a/icu/source/common/ubrk.cpp b/icu/source/common/ubrk.cpp
new file mode 100644
index 0000000..944708a
--- /dev/null
+++ b/icu/source/common/ubrk.cpp
@@ -0,0 +1,293 @@
+/*
+********************************************************************************
+*   Copyright (C) 1996-2008, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+********************************************************************************
+*/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+#include "unicode/ubrk.h"
+
+#include "unicode/brkiter.h"
+#include "unicode/uloc.h"
+#include "unicode/ustring.h"
+#include "unicode/uchriter.h"
+#include "unicode/rbbi.h"
+#include "rbbirb.h"
+#include "uassert.h"
+
+U_NAMESPACE_USE
+
+//------------------------------------------------------------------------------
+//
+//    ubrk_open      Create a canned type of break iterator based on type (word, line, etc.)
+//                   and locale.
+//
+//------------------------------------------------------------------------------
+U_CAPI UBreakIterator* U_EXPORT2
+ubrk_open(UBreakIteratorType type,
+      const char *locale,
+      const UChar *text,
+      int32_t textLength,
+      UErrorCode *status)
+{
+
+  if(U_FAILURE(*status)) return 0;
+
+  BreakIterator *result = 0;
+
+  switch(type) {
+
+  case UBRK_CHARACTER:
+    result = BreakIterator::createCharacterInstance(Locale(locale), *status);
+    break;
+
+  case UBRK_WORD:
+    result = BreakIterator::createWordInstance(Locale(locale), *status);
+    break;
+
+  case UBRK_LINE:
+    result = BreakIterator::createLineInstance(Locale(locale), *status);
+    break;
+
+  case UBRK_SENTENCE:
+    result = BreakIterator::createSentenceInstance(Locale(locale), *status);
+    break;
+
+  case UBRK_TITLE:
+    result = BreakIterator::createTitleInstance(Locale(locale), *status);
+    break;
+
+  default:
+    *status = U_ILLEGAL_ARGUMENT_ERROR;
+  }
+
+  // check for allocation error
+  if (U_FAILURE(*status)) {
+     return 0;
+  }
+  if(result == 0) {
+    *status = U_MEMORY_ALLOCATION_ERROR;
+    return 0;
+  }
+
+
+  UBreakIterator *uBI = (UBreakIterator *)result;
+  if (text != NULL) {
+      ubrk_setText(uBI, text, textLength, status);
+  }
+  return uBI;
+}
+
+
+
+//------------------------------------------------------------------------------
+//
+//   ubrk_openRules      open a break iterator from a set of break rules.
+//                       Invokes the rule builder.
+//
+//------------------------------------------------------------------------------
+U_CAPI UBreakIterator* U_EXPORT2
+ubrk_openRules(  const UChar        *rules,
+                       int32_t       rulesLength,
+                 const UChar        *text,
+                       int32_t       textLength,
+                       UParseError  *parseErr,
+                       UErrorCode   *status)  {
+
+    if (status == NULL || U_FAILURE(*status)){
+        return 0;
+    }
+
+    BreakIterator *result = 0;
+    UnicodeString ruleString(rules, rulesLength);
+    result = RBBIRuleBuilder::createRuleBasedBreakIterator(ruleString, parseErr, *status);
+    if(U_FAILURE(*status)) {
+        return 0;
+    }
+
+    UBreakIterator *uBI = (UBreakIterator *)result;
+    if (text != NULL) {
+        ubrk_setText(uBI, text, textLength, status);
+    }
+    return uBI;
+}
+
+
+
+
+
+U_CAPI UBreakIterator * U_EXPORT2
+ubrk_safeClone(
+          const UBreakIterator *bi,
+          void *stackBuffer,
+          int32_t *pBufferSize,
+          UErrorCode *status)
+{
+    if (status == NULL || U_FAILURE(*status)){
+        return 0;
+    }
+    if (!pBufferSize || !bi){
+       *status = U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+    // Clear any incoming Safe Clone Allocated warning.
+    //  Propagating this through to our return would really
+    //  confuse our caller.
+    if (*status==U_SAFECLONE_ALLOCATED_WARNING) {
+        *status = U_ZERO_ERROR;
+    }
+    return (UBreakIterator *)(((BreakIterator*)bi)->
+        createBufferClone(stackBuffer, *pBufferSize, *status));
+}
+
+
+
+U_CAPI void U_EXPORT2
+ubrk_close(UBreakIterator *bi)
+{
+    BreakIterator *ubi = (BreakIterator*) bi;
+    if (ubi) {
+        if (ubi->isBufferClone()) {
+            ubi->~BreakIterator();
+            *(uint32_t *)ubi = 0xdeadbeef;
+        } else {
+            delete ubi;
+        }
+    }
+}
+
+U_CAPI void U_EXPORT2
+ubrk_setText(UBreakIterator* bi,
+             const UChar*    text,
+             int32_t         textLength,
+             UErrorCode*     status)
+{
+    BreakIterator *brit = (BreakIterator *)bi;
+    UText  ut = UTEXT_INITIALIZER;
+    utext_openUChars(&ut, text, textLength, status);
+    brit->setText(&ut, *status);
+    // A stack allocated UText wrapping a UCHar * string
+    //   can be dumped without explicitly closing it.
+}
+
+
+
+U_CAPI void U_EXPORT2
+ubrk_setUText(UBreakIterator *bi,
+             UText          *text,
+             UErrorCode     *status)
+{
+    RuleBasedBreakIterator *brit = (RuleBasedBreakIterator *)bi;
+    brit->RuleBasedBreakIterator::setText(text, *status);
+}
+
+
+
+
+
+U_CAPI int32_t U_EXPORT2
+ubrk_current(const UBreakIterator *bi)
+{
+
+  return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::current();
+}
+
+U_CAPI int32_t U_EXPORT2
+ubrk_next(UBreakIterator *bi)
+{
+
+  return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::next();
+}
+
+U_CAPI int32_t U_EXPORT2
+ubrk_previous(UBreakIterator *bi)
+{
+
+  return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::previous();
+}
+
+U_CAPI int32_t U_EXPORT2
+ubrk_first(UBreakIterator *bi)
+{
+
+  return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::first();
+}
+
+U_CAPI int32_t U_EXPORT2
+ubrk_last(UBreakIterator *bi)
+{
+
+  return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::last();
+}
+
+U_CAPI int32_t U_EXPORT2
+ubrk_preceding(UBreakIterator *bi,
+           int32_t offset)
+{
+
+  return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::preceding(offset);
+}
+
+U_CAPI int32_t U_EXPORT2
+ubrk_following(UBreakIterator *bi,
+           int32_t offset)
+{
+
+  return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::following(offset);
+}
+
+U_CAPI const char* U_EXPORT2
+ubrk_getAvailable(int32_t index)
+{
+
+  return uloc_getAvailable(index);
+}
+
+U_CAPI int32_t U_EXPORT2
+ubrk_countAvailable()
+{
+
+  return uloc_countAvailable();
+}
+
+
+U_CAPI  UBool U_EXPORT2
+ubrk_isBoundary(UBreakIterator *bi, int32_t offset)
+{
+    return ((RuleBasedBreakIterator *)bi)->RuleBasedBreakIterator::isBoundary(offset);
+}
+
+
+U_CAPI  int32_t U_EXPORT2
+ubrk_getRuleStatus(UBreakIterator *bi)
+{
+    return ((RuleBasedBreakIterator *)bi)->RuleBasedBreakIterator::getRuleStatus();
+}
+
+U_CAPI  int32_t U_EXPORT2
+ubrk_getRuleStatusVec(UBreakIterator *bi, int32_t *fillInVec, int32_t capacity, UErrorCode *status)
+{
+    return ((RuleBasedBreakIterator *)bi)->RuleBasedBreakIterator::getRuleStatusVec(fillInVec, capacity, *status);
+}
+
+
+U_CAPI const char* U_EXPORT2
+ubrk_getLocaleByType(const UBreakIterator *bi,
+                     ULocDataLocaleType type,
+                     UErrorCode* status)
+{
+    if (bi == NULL) {
+        if (U_SUCCESS(*status)) {
+            *status = U_ILLEGAL_ARGUMENT_ERROR;
+        }
+        return NULL;
+    }
+    return ((BreakIterator*)bi)->getLocaleID(type, *status);
+}
+
+
+#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
diff --git a/icu/source/common/ubrkimpl.h b/icu/source/common/ubrkimpl.h
new file mode 100644
index 0000000..e490971
--- /dev/null
+++ b/icu/source/common/ubrkimpl.h
@@ -0,0 +1,13 @@
+/*
+**********************************************************************
+*   Copyright (C) 2006, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*/
+
+#ifndef UBRKIMPL_H
+#define UBRKIMPL_H
+
+#define U_ICUDATA_BRKITR U_ICUDATA_NAME U_TREE_SEPARATOR_STRING "brkitr"
+
+#endif /*UBRKIMPL_H*/
diff --git a/icu/source/common/ucase.c b/icu/source/common/ucase.c
new file mode 100644
index 0000000..421ade4
--- /dev/null
+++ b/icu/source/common/ucase.c
@@ -0,0 +1,1631 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2004-2009, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  ucase.c
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2004aug30
+*   created by: Markus W. Scherer
+*
+*   Low-level Unicode character/string case mapping code.
+*   Much code moved here (and modified) from uchar.c.
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/uset.h"
+#include "unicode/udata.h" /* UDataInfo */
+#include "ucmndata.h" /* DataHeader */
+#include "udatamem.h"
+#include "umutex.h"
+#include "uassert.h"
+#include "cmemory.h"
+#include "utrie2.h"
+#include "ucase.h"
+#include "ucln_cmn.h"
+
+struct UCaseProps {
+    UDataMemory *mem;
+    const int32_t *indexes;
+    const uint16_t *exceptions;
+    const UChar *unfold;
+
+    UTrie2 trie;
+    uint8_t formatVersion[4];
+};
+
+/* data loading etc. -------------------------------------------------------- */
+
+#if UCASE_HARDCODE_DATA
+
+/* ucase_props_data.c is machine-generated by gencase --csource */
+#include "ucase_props_data.c"
+
+#else
+
+static UBool U_CALLCONV
+isAcceptable(void *context,
+             const char *type, const char *name,
+             const UDataInfo *pInfo) {
+    if(
+        pInfo->size>=20 &&
+        pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
+        pInfo->charsetFamily==U_CHARSET_FAMILY &&
+        pInfo->dataFormat[0]==UCASE_FMT_0 &&    /* dataFormat="cAsE" */
+        pInfo->dataFormat[1]==UCASE_FMT_1 &&
+        pInfo->dataFormat[2]==UCASE_FMT_2 &&
+        pInfo->dataFormat[3]==UCASE_FMT_3 &&
+        pInfo->formatVersion[0]==1 &&
+        pInfo->formatVersion[2]==UTRIE_SHIFT &&
+        pInfo->formatVersion[3]==UTRIE_INDEX_SHIFT
+    ) {
+        UCaseProps *csp=(UCaseProps *)context;
+        uprv_memcpy(csp->formatVersion, pInfo->formatVersion, 4);
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+
+static UCaseProps *
+ucase_openData(UCaseProps *cspProto,
+               const uint8_t *bin, int32_t length, UErrorCode *pErrorCode) {
+    UCaseProps *csp;
+    int32_t size;
+
+    cspProto->indexes=(const int32_t *)bin;
+    if( (length>=0 && length<16*4) ||
+        cspProto->indexes[UCASE_IX_INDEX_TOP]<16
+    ) {
+        /* length or indexes[] too short for minimum indexes[] length of 16 */
+        *pErrorCode=U_INVALID_FORMAT_ERROR;
+        return NULL;
+    }
+    size=cspProto->indexes[UCASE_IX_INDEX_TOP]*4;
+    if(length>=0) {
+        if(length>=size && length>=cspProto->indexes[UCASE_IX_LENGTH]) {
+            length-=size;
+        } else {
+            /* length too short for indexes[] or for the whole data length */
+            *pErrorCode=U_INVALID_FORMAT_ERROR;
+            return NULL;
+        }
+    }
+    bin+=size;
+    /* from here on, assume that the sizes of the items fit into the total length */
+
+    /* unserialize the trie, after indexes[] */
+    size=cspProto->indexes[UCASE_IX_TRIE_SIZE];
+    utrie_unserialize(&cspProto->trie, bin, size, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+    bin+=size;
+
+    /* get exceptions[] */
+    size=2*cspProto->indexes[UCASE_IX_EXC_LENGTH];
+    cspProto->exceptions=(const uint16_t *)bin;
+    bin+=size;
+
+    /* get unfold[] */
+    size=2*cspProto->indexes[UCASE_IX_UNFOLD_LENGTH];
+    if(size!=0) {
+        cspProto->unfold=(const UChar *)bin;
+        bin+=size;
+    } else {
+        cspProto->unfold=NULL;
+    }
+
+    /* allocate, copy, and return the new UCaseProps */
+    csp=(UCaseProps *)uprv_malloc(sizeof(UCaseProps));
+    if(csp==NULL) {
+        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+        return NULL;
+    } else {
+        uprv_memcpy(csp, cspProto, sizeof(UCaseProps));
+        return csp;
+    }
+}
+
+U_CAPI UCaseProps * U_EXPORT2
+ucase_open(UErrorCode *pErrorCode) {
+    UCaseProps cspProto={ NULL }, *csp;
+
+    cspProto.mem=udata_openChoice(NULL, UCASE_DATA_TYPE, UCASE_DATA_NAME, isAcceptable, &cspProto, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+
+    csp=ucase_openData(
+            &cspProto,
+            udata_getMemory(cspProto.mem),
+            udata_getLength(cspProto.mem),
+            pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        udata_close(cspProto.mem);
+        return NULL;
+    } else {
+        return csp;
+    }
+}
+
+U_CAPI UCaseProps * U_EXPORT2
+ucase_openBinary(const uint8_t *bin, int32_t length, UErrorCode *pErrorCode) {
+    UCaseProps cspProto={ NULL };
+    const DataHeader *hdr;
+
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+    if(bin==NULL) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return NULL;
+    }
+
+    /* check the header */
+    if(length>=0 && length<20) {
+        *pErrorCode=U_INVALID_FORMAT_ERROR;
+        return NULL;
+    }
+    hdr=(const DataHeader *)bin;
+    if(
+        !(hdr->dataHeader.magic1==0xda && hdr->dataHeader.magic2==0x27 &&
+          hdr->info.isBigEndian==U_IS_BIG_ENDIAN &&
+          isAcceptable(&cspProto, UCASE_DATA_TYPE, UCASE_DATA_NAME, &hdr->info))
+    ) {
+        *pErrorCode=U_INVALID_FORMAT_ERROR;
+        return NULL;
+    }
+
+    bin+=hdr->dataHeader.headerSize;
+    if(length>=0) {
+        length-=hdr->dataHeader.headerSize;
+    }
+    return ucase_openData(&cspProto, bin, length, pErrorCode);
+}
+
+#endif
+
+U_CAPI void U_EXPORT2
+ucase_close(UCaseProps *csp) {
+    if(csp!=NULL) {
+#if !UCASE_HARDCODE_DATA
+        udata_close(csp->mem);
+#endif
+        uprv_free(csp);
+    }
+}
+
+/* UCaseProps singleton ----------------------------------------------------- */
+
+#if !UCASE_HARDCODE_DATA
+static UCaseProps *gCsp=NULL;
+static UCaseProps *gCspDummy=NULL;
+static UErrorCode gErrorCode=U_ZERO_ERROR;
+static int8_t gHaveData=0;
+#endif
+
+#if !UCASE_HARDCODE_DATA
+static UBool U_CALLCONV ucase_cleanup(void) {
+    ucase_close(gCsp);
+    gCsp=NULL;
+    ucase_close(gCspDummy);
+    gCspDummy=NULL;
+    gErrorCode=U_ZERO_ERROR;
+    gHaveData=0;
+    return TRUE;
+}
+#endif
+
+U_CAPI const UCaseProps * U_EXPORT2
+ucase_getSingleton(UErrorCode *pErrorCode) {
+#if UCASE_HARDCODE_DATA
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+    return &ucase_props_singleton;
+#else
+    int8_t haveData;
+
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+
+    UMTX_CHECK(NULL, gHaveData, haveData);
+
+    if(haveData>0) {
+        /* data was loaded */
+        return gCsp;
+    } else if(haveData<0) {
+        /* data loading failed */
+        *pErrorCode=gErrorCode;
+        return NULL;
+    } else /* haveData==0 */ {
+        /* load the data */
+        UCaseProps *csp=ucase_open(pErrorCode);
+        if(U_FAILURE(*pErrorCode)) {
+            gHaveData=-1;
+            gErrorCode=*pErrorCode;
+            return NULL;
+        }
+
+        /* set the static variables */
+        umtx_lock(NULL);
+        if(gCsp==NULL) {
+            gCsp=csp;
+            csp=NULL;
+            gHaveData=1;
+            ucln_common_registerCleanup(UCLN_COMMON_UCASE, ucase_cleanup);
+        }
+        umtx_unlock(NULL);
+
+        ucase_close(csp);
+        return gCsp;
+    }
+#endif
+}
+
+#if !UCASE_HARDCODE_DATA
+U_CAPI const UCaseProps * U_EXPORT2
+ucase_getDummy(UErrorCode *pErrorCode) {
+    UCaseProps *csp;
+
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+
+    UMTX_CHECK(NULL, gCspDummy, csp);
+
+    if(csp!=NULL) {
+        /* the dummy object was already created */
+        return csp;
+    } else /* csp==NULL */ {
+        /* create the dummy object */
+        int32_t *indexes;
+        
+        csp=(UCaseProps *)uprv_malloc(sizeof(UCaseProps)+UCASE_IX_TOP*4+UTRIE_DUMMY_SIZE);
+        if(csp==NULL) {
+            *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+            return NULL;
+        }
+        uprv_memset(csp, 0, sizeof(UCaseProps)+UCASE_IX_TOP*4);
+
+        csp->indexes=indexes=(int32_t *)(csp+1);
+        indexes[UCASE_IX_INDEX_TOP]=UCASE_IX_TOP;
+
+        indexes[UCASE_IX_TRIE_SIZE]=
+            utrie_unserializeDummy(&csp->trie, indexes+UCASE_IX_TOP, UTRIE_DUMMY_SIZE, 0, 0, TRUE, pErrorCode);
+        if(U_FAILURE(*pErrorCode)) {
+            uprv_free(csp);
+            return NULL;
+        }
+
+        csp->formatVersion[0]=1;
+        csp->formatVersion[2]=UTRIE_SHIFT;
+        csp->formatVersion[3]=UTRIE_INDEX_SHIFT;
+
+        /* set the static variables */
+        umtx_lock(NULL);
+        if(gCspDummy==NULL) {
+            gCspDummy=csp;
+            csp=NULL;
+            ucln_common_registerCleanup(UCLN_COMMON_UCASE, ucase_cleanup);
+        }
+        umtx_unlock(NULL);
+
+        uprv_free(csp);
+        return gCspDummy;
+    }
+}
+#endif
+
+/* set of property starts for UnicodeSet ------------------------------------ */
+
+static UBool U_CALLCONV
+_enumPropertyStartsRange(const void *context, UChar32 start, UChar32 end, uint32_t value) {
+    /* add the start code point to the USet */
+    const USetAdder *sa=(const USetAdder *)context;
+    sa->add(sa->set, start);
+    return TRUE;
+}
+
+U_CFUNC void U_EXPORT2
+ucase_addPropertyStarts(const UCaseProps *csp, const USetAdder *sa, UErrorCode *pErrorCode) {
+    if(U_FAILURE(*pErrorCode)) {
+        return;
+    }
+
+    /* add the start code point of each same-value range of the trie */
+    utrie2_enum(&csp->trie, NULL, _enumPropertyStartsRange, sa);
+
+    /* add code points with hardcoded properties, plus the ones following them */
+
+    /* (none right now, see comment below) */
+
+    /*
+     * Omit code points with hardcoded specialcasing properties
+     * because we do not build property UnicodeSets for them right now.
+     */
+}
+
+/* data access primitives --------------------------------------------------- */
+
+#define GET_EXCEPTIONS(csp, props) ((csp)->exceptions+((props)>>UCASE_EXC_SHIFT))
+
+#define PROPS_HAS_EXCEPTION(props) ((props)&UCASE_EXCEPTION)
+
+/* number of bits in an 8-bit integer value */
+static const uint8_t flagsOffset[256]={
+    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+    4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+};
+
+#define HAS_SLOT(flags, idx) ((flags)&(1<<(idx)))
+#define SLOT_OFFSET(flags, idx) flagsOffset[(flags)&((1<<(idx))-1)]
+
+/*
+ * Get the value of an optional-value slot where HAS_SLOT(excWord, idx).
+ *
+ * @param excWord (in) initial exceptions word
+ * @param idx (in) desired slot index
+ * @param pExc16 (in/out) const uint16_t * after excWord=*pExc16++;
+ *               moved to the last uint16_t of the value, use +1 for beginning of next slot
+ * @param value (out) int32_t or uint32_t output if hasSlot, otherwise not modified
+ */
+#define GET_SLOT_VALUE(excWord, idx, pExc16, value) \
+    if(((excWord)&UCASE_EXC_DOUBLE_SLOTS)==0) { \
+        (pExc16)+=SLOT_OFFSET(excWord, idx); \
+        (value)=*pExc16; \
+    } else { \
+        (pExc16)+=2*SLOT_OFFSET(excWord, idx); \
+        (value)=*pExc16++; \
+        (value)=((value)<<16)|*pExc16; \
+    }
+
+/* simple case mappings ----------------------------------------------------- */
+
+U_CAPI UChar32 U_EXPORT2
+ucase_tolower(const UCaseProps *csp, UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&csp->trie, c);
+    if(!PROPS_HAS_EXCEPTION(props)) {
+        if(UCASE_GET_TYPE(props)>=UCASE_UPPER) {
+            c+=UCASE_GET_DELTA(props);
+        }
+    } else {
+        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
+        uint16_t excWord=*pe++;
+        if(HAS_SLOT(excWord, UCASE_EXC_LOWER)) {
+            GET_SLOT_VALUE(excWord, UCASE_EXC_LOWER, pe, c);
+        }
+    }
+    return c;
+}
+
+U_CAPI UChar32 U_EXPORT2
+ucase_toupper(const UCaseProps *csp, UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&csp->trie, c);
+    if(!PROPS_HAS_EXCEPTION(props)) {
+        if(UCASE_GET_TYPE(props)==UCASE_LOWER) {
+            c+=UCASE_GET_DELTA(props);
+        }
+    } else {
+        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
+        uint16_t excWord=*pe++;
+        if(HAS_SLOT(excWord, UCASE_EXC_UPPER)) {
+            GET_SLOT_VALUE(excWord, UCASE_EXC_UPPER, pe, c);
+        }
+    }
+    return c;
+}
+
+U_CAPI UChar32 U_EXPORT2
+ucase_totitle(const UCaseProps *csp, UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&csp->trie, c);
+    if(!PROPS_HAS_EXCEPTION(props)) {
+        if(UCASE_GET_TYPE(props)==UCASE_LOWER) {
+            c+=UCASE_GET_DELTA(props);
+        }
+    } else {
+        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
+        uint16_t excWord=*pe++;
+        int32_t idx;
+        if(HAS_SLOT(excWord, UCASE_EXC_TITLE)) {
+            idx=UCASE_EXC_TITLE;
+        } else if(HAS_SLOT(excWord, UCASE_EXC_UPPER)) {
+            idx=UCASE_EXC_UPPER;
+        } else {
+            return c;
+        }
+        GET_SLOT_VALUE(excWord, idx, pe, c);
+    }
+    return c;
+}
+
+static const UChar iDot[2] = { 0x69, 0x307 };
+static const UChar jDot[2] = { 0x6a, 0x307 };
+static const UChar iOgonekDot[3] = { 0x12f, 0x307 };
+static const UChar iDotGrave[3] = { 0x69, 0x307, 0x300 };
+static const UChar iDotAcute[3] = { 0x69, 0x307, 0x301 };
+static const UChar iDotTilde[3] = { 0x69, 0x307, 0x303 };
+
+
+U_CFUNC void U_EXPORT2
+ucase_addCaseClosure(const UCaseProps *csp, UChar32 c, const USetAdder *sa) {
+    uint16_t props;
+
+    /*
+     * Hardcode the case closure of i and its relatives and ignore the
+     * data file data for these characters.
+     * The Turkic dotless i and dotted I with their case mapping conditions
+     * and case folding option make the related characters behave specially.
+     * This code matches their closure behavior to their case folding behavior.
+     */
+
+    switch(c) {
+    case 0x49:
+        /* regular i and I are in one equivalence class */
+        sa->add(sa->set, 0x69);
+        return;
+    case 0x69:
+        sa->add(sa->set, 0x49);
+        return;
+    case 0x130:
+        /* dotted I is in a class with <0069 0307> (for canonical equivalence with <0049 0307>) */
+        sa->addString(sa->set, iDot, 2);
+        return;
+    case 0x131:
+        /* dotless i is in a class by itself */
+        return;
+    default:
+        /* otherwise use the data file data */
+        break;
+    }
+
+    props=UTRIE2_GET16(&csp->trie, c);
+    if(!PROPS_HAS_EXCEPTION(props)) {
+        if(UCASE_GET_TYPE(props)!=UCASE_NONE) {
+            /* add the one simple case mapping, no matter what type it is */
+            int32_t delta=UCASE_GET_DELTA(props);
+            if(delta!=0) {
+                sa->add(sa->set, c+delta);
+            }
+        }
+    } else {
+        /*
+         * c has exceptions, so there may be multiple simple and/or
+         * full case mappings. Add them all.
+         */
+        const uint16_t *pe0, *pe=GET_EXCEPTIONS(csp, props);
+        const UChar *closure;
+        uint16_t excWord=*pe++;
+        int32_t idx, closureLength, fullLength, length;
+
+        pe0=pe;
+
+        /* add all simple case mappings */
+        for(idx=UCASE_EXC_LOWER; idx<=UCASE_EXC_TITLE; ++idx) {
+            if(HAS_SLOT(excWord, idx)) {
+                pe=pe0;
+                GET_SLOT_VALUE(excWord, idx, pe, c);
+                sa->add(sa->set, c);
+            }
+        }
+
+        /* get the closure string pointer & length */
+        if(HAS_SLOT(excWord, UCASE_EXC_CLOSURE)) {
+            pe=pe0;
+            GET_SLOT_VALUE(excWord, UCASE_EXC_CLOSURE, pe, closureLength);
+            closureLength&=UCASE_CLOSURE_MAX_LENGTH; /* higher bits are reserved */
+            closure=(const UChar *)pe+1; /* behind this slot, unless there are full case mappings */
+        } else {
+            closureLength=0;
+            closure=NULL;
+        }
+
+        /* add the full case folding */
+        if(HAS_SLOT(excWord, UCASE_EXC_FULL_MAPPINGS)) {
+            pe=pe0;
+            GET_SLOT_VALUE(excWord, UCASE_EXC_FULL_MAPPINGS, pe, fullLength);
+
+            /* start of full case mapping strings */
+            ++pe;
+
+            fullLength&=0xffff; /* bits 16 and higher are reserved */
+
+            /* skip the lowercase result string */
+            pe+=fullLength&UCASE_FULL_LOWER;
+            fullLength>>=4;
+
+            /* add the full case folding string */
+            length=fullLength&0xf;
+            if(length!=0) {
+                sa->addString(sa->set, (const UChar *)pe, length);
+                pe+=length;
+            }
+
+            /* skip the uppercase and titlecase strings */
+            fullLength>>=4;
+            pe+=fullLength&0xf;
+            fullLength>>=4;
+            pe+=fullLength;
+
+            closure=(const UChar *)pe; /* behind full case mappings */
+        }
+
+        /* add each code point in the closure string */
+        for(idx=0; idx<closureLength;) {
+            U16_NEXT_UNSAFE(closure, idx, c);
+            sa->add(sa->set, c);
+        }
+    }
+}
+
+/*
+ * compare s, which has a length, with t, which has a maximum length or is NUL-terminated
+ * must be length>0 and max>0 and length<=max
+ */
+static U_INLINE int32_t
+strcmpMax(const UChar *s, int32_t length, const UChar *t, int32_t max) {
+    int32_t c1, c2;
+
+    max-=length; /* we require length<=max, so no need to decrement max in the loop */
+    do {
+        c1=*s++;
+        c2=*t++;
+        if(c2==0) {
+            return 1; /* reached the end of t but not of s */
+        }
+        c1-=c2;
+        if(c1!=0) {
+            return c1; /* return difference result */
+        }
+    } while(--length>0);
+    /* ends with length==0 */
+
+    if(max==0 || *t==0) {
+        return 0; /* equal to length of both strings */
+    } else {
+        return -max; /* return lengh difference */
+    }
+}
+
+U_CFUNC UBool U_EXPORT2
+ucase_addStringCaseClosure(const UCaseProps *csp, const UChar *s, int32_t length, const USetAdder *sa) {
+    const UChar *unfold, *p;
+    int32_t i, start, limit, result, unfoldRows, unfoldRowWidth, unfoldStringWidth;
+
+    if(csp->unfold==NULL || s==NULL) {
+        return FALSE; /* no reverse case folding data, or no string */
+    }
+    if(length<=1) {
+        /* the string is too short to find any match */
+        /*
+         * more precise would be:
+         * if(!u_strHasMoreChar32Than(s, length, 1))
+         * but this does not make much practical difference because
+         * a single supplementary code point would just not be found
+         */
+        return FALSE;
+    }
+
+    unfold=csp->unfold;
+    unfoldRows=unfold[UCASE_UNFOLD_ROWS];
+    unfoldRowWidth=unfold[UCASE_UNFOLD_ROW_WIDTH];
+    unfoldStringWidth=unfold[UCASE_UNFOLD_STRING_WIDTH];
+    unfold+=unfoldRowWidth;
+
+    if(length>unfoldStringWidth) {
+        /* the string is too long to find any match */
+        return FALSE;
+    }
+
+    /* do a binary search for the string */
+    start=0;
+    limit=unfoldRows;
+    while(start<limit) {
+        i=(start+limit)/2;
+        p=unfold+(i*unfoldRowWidth);
+        result=strcmpMax(s, length, p, unfoldStringWidth);
+
+        if(result==0) {
+            /* found the string: add each code point, and its case closure */
+            UChar32 c;
+
+            for(i=unfoldStringWidth; i<unfoldRowWidth && p[i]!=0;) {
+                U16_NEXT_UNSAFE(p, i, c);
+                sa->add(sa->set, c);
+                ucase_addCaseClosure(csp, c, sa);
+            }
+            return TRUE;
+        } else if(result<0) {
+            limit=i;
+        } else /* result>0 */ {
+            start=i+1;
+        }
+    }
+
+    return FALSE; /* string not found */
+}
+
+/** @return UCASE_NONE, UCASE_LOWER, UCASE_UPPER, UCASE_TITLE */
+U_CAPI int32_t U_EXPORT2
+ucase_getType(const UCaseProps *csp, UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&csp->trie, c);
+    return UCASE_GET_TYPE(props);
+}
+
+/** @return same as ucase_getType() and set bit 2 if c is case-ignorable */
+U_CAPI int32_t U_EXPORT2
+ucase_getTypeOrIgnorable(const UCaseProps *csp, UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&csp->trie, c);
+    int32_t type=UCASE_GET_TYPE(props);
+    if(props&UCASE_EXCEPTION) {
+        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
+        if(*pe&UCASE_EXC_CASE_IGNORABLE) {
+            type|=4;
+        }
+    } else if(type==UCASE_NONE && (props&UCASE_CASE_IGNORABLE)) {
+        type|=4;
+    }
+    return type;
+}
+
+/** @return UCASE_NO_DOT, UCASE_SOFT_DOTTED, UCASE_ABOVE, UCASE_OTHER_ACCENT */
+static U_INLINE int32_t
+getDotType(const UCaseProps *csp, UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&csp->trie, c);
+    if(!PROPS_HAS_EXCEPTION(props)) {
+        return props&UCASE_DOT_MASK;
+    } else {
+        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
+        return (*pe>>UCASE_EXC_DOT_SHIFT)&UCASE_DOT_MASK;
+    }
+}
+
+U_CAPI UBool U_EXPORT2
+ucase_isSoftDotted(const UCaseProps *csp, UChar32 c) {
+    return (UBool)(getDotType(csp, c)==UCASE_SOFT_DOTTED);
+}
+
+U_CAPI UBool U_EXPORT2
+ucase_isCaseSensitive(const UCaseProps *csp, UChar32 c) {
+    uint16_t props=UTRIE2_GET16(&csp->trie, c);
+    return (UBool)((props&UCASE_SENSITIVE)!=0);
+}
+
+/* string casing ------------------------------------------------------------ */
+
+/*
+ * These internal functions form the core of string case mappings.
+ * They map single code points to result code points or strings and take
+ * all necessary conditions (context, locale ID, options) into account.
+ *
+ * They do not iterate over the source or write to the destination
+ * so that the same functions are useful for non-standard string storage,
+ * such as in a Replaceable (for Transliterator) or UTF-8/32 strings etc.
+ * For the same reason, the "surrounding text" context is passed in as a
+ * UCaseContextIterator which does not make any assumptions about
+ * the underlying storage.
+ *
+ * This section contains helper functions that check for conditions
+ * in the input text surrounding the current code point
+ * according to SpecialCasing.txt.
+ *
+ * Each helper function gets the index
+ * - after the current code point if it looks at following text
+ * - before the current code point if it looks at preceding text
+ *
+ * Unicode 3.2 UAX 21 "Case Mappings" defines the conditions as follows:
+ *
+ * Final_Sigma
+ *   C is preceded by a sequence consisting of
+ *     a cased letter and a case-ignorable sequence,
+ *   and C is not followed by a sequence consisting of
+ *     an ignorable sequence and then a cased letter.
+ *
+ * More_Above
+ *   C is followed by one or more characters of combining class 230 (ABOVE)
+ *   in the combining character sequence.
+ *
+ * After_Soft_Dotted
+ *   The last preceding character with combining class of zero before C
+ *   was Soft_Dotted,
+ *   and there is no intervening combining character class 230 (ABOVE).
+ *
+ * Before_Dot
+ *   C is followed by combining dot above (U+0307).
+ *   Any sequence of characters with a combining class that is neither 0 nor 230
+ *   may intervene between the current character and the combining dot above.
+ *
+ * The erratum from 2002-10-31 adds the condition
+ *
+ * After_I
+ *   The last preceding base character was an uppercase I, and there is no
+ *   intervening combining character class 230 (ABOVE).
+ *
+ *   (See Jitterbug 2344 and the comments on After_I below.)
+ *
+ * Helper definitions in Unicode 3.2 UAX 21:
+ *
+ * D1. A character C is defined to be cased
+ *     if it meets any of the following criteria:
+ *
+ *   - The general category of C is Titlecase Letter (Lt)
+ *   - In [CoreProps], C has one of the properties Uppercase, or Lowercase
+ *   - Given D = NFD(C), then it is not the case that:
+ *     D = UCD_lower(D) = UCD_upper(D) = UCD_title(D)
+ *     (This third criterium does not add any characters to the list
+ *      for Unicode 3.2. Ignored.)
+ *
+ * D2. A character C is defined to be case-ignorable
+ *     if it meets either of the following criteria:
+ *
+ *   - The general category of C is
+ *     Nonspacing Mark (Mn), or Enclosing Mark (Me), or Format Control (Cf), or
+ *     Letter Modifier (Lm), or Symbol Modifier (Sk)
+ *   - C is one of the following characters 
+ *     U+0027 APOSTROPHE
+ *     U+00AD SOFT HYPHEN (SHY)
+ *     U+2019 RIGHT SINGLE QUOTATION MARK
+ *            (the preferred character for apostrophe)
+ *
+ * D3. A case-ignorable sequence is a sequence of
+ *     zero or more case-ignorable characters.
+ */
+
+#define is_a(c) ((c)=='a' || (c)=='A')
+#define is_d(c) ((c)=='d' || (c)=='D')
+#define is_e(c) ((c)=='e' || (c)=='E')
+#define is_i(c) ((c)=='i' || (c)=='I')
+#define is_l(c) ((c)=='l' || (c)=='L')
+#define is_n(c) ((c)=='n' || (c)=='N')
+#define is_r(c) ((c)=='r' || (c)=='R')
+#define is_t(c) ((c)=='t' || (c)=='T')
+#define is_u(c) ((c)=='u' || (c)=='U')
+#define is_z(c) ((c)=='z' || (c)=='Z')
+
+/* separator? */
+#define is_sep(c) ((c)=='_' || (c)=='-' || (c)==0)
+
+/**
+ * Requires non-NULL locale ID but otherwise does the equivalent of
+ * checking for language codes as if uloc_getLanguage() were called:
+ * Accepts both 2- and 3-letter codes and accepts case variants.
+ */
+U_CFUNC int32_t
+ucase_getCaseLocale(const char *locale, int32_t *locCache) {
+    int32_t result;
+    char c;
+
+    if(locCache!=NULL && (result=*locCache)!=UCASE_LOC_UNKNOWN) {
+        return result;
+    }
+
+    result=UCASE_LOC_ROOT;
+
+    /*
+     * This function used to use uloc_getLanguage(), but the current code
+     * removes the dependency of this low-level code on uloc implementation code
+     * and is faster because not the whole locale ID has to be
+     * examined and copied/transformed.
+     *
+     * Because this code does not want to depend on uloc, the caller must
+     * pass in a non-NULL locale, i.e., may need to call uloc_getDefault().
+     */
+    c=*locale++;
+    if(is_t(c)) {
+        /* tr or tur? */
+        c=*locale++;
+        if(is_u(c)) {
+            c=*locale++;
+        }
+        if(is_r(c)) {
+            c=*locale;
+            if(is_sep(c)) {
+                result=UCASE_LOC_TURKISH;
+            }
+        }
+    } else if(is_a(c)) {
+        /* az or aze? */
+        c=*locale++;
+        if(is_z(c)) {
+            c=*locale++;
+            if(is_e(c)) {
+                c=*locale;
+            }
+            if(is_sep(c)) {
+                result=UCASE_LOC_TURKISH;
+            }
+        }
+    } else if(is_l(c)) {
+        /* lt or lit? */
+        c=*locale++;
+        if(is_i(c)) {
+            c=*locale++;
+        }
+        if(is_t(c)) {
+            c=*locale;
+            if(is_sep(c)) {
+                result=UCASE_LOC_LITHUANIAN;
+            }
+        }
+    } else if(is_n(c)) {
+        /* nl or nld? */
+        c=*locale++;
+        if(is_l(c)) {
+            c=*locale++;
+            if(is_d(c)) {
+                c=*locale;
+            }
+            if(is_sep(c)) {
+                result=UCASE_LOC_DUTCH;
+            }
+        }
+    }
+
+    if(locCache!=NULL) {
+        *locCache=result;
+    }
+    return result;
+}
+
+/*
+ * Is followed by
+ *   {case-ignorable}* cased
+ * ?
+ * (dir determines looking forward/backward)
+ * If a character is case-ignorable, it is skipped regardless of whether
+ * it is also cased or not.
+ */
+static UBool
+isFollowedByCasedLetter(const UCaseProps *csp, UCaseContextIterator *iter, void *context, int8_t dir) {
+    UChar32 c;
+
+    if(iter==NULL) {
+        return FALSE;
+    }
+
+    for(/* dir!=0 sets direction */; (c=iter(context, dir))>=0; dir=0) {
+        int32_t type=ucase_getTypeOrIgnorable(csp, c);
+        if(type&4) {
+            /* case-ignorable, continue with the loop */
+        } else if(type!=UCASE_NONE) {
+            return TRUE; /* followed by cased letter */
+        } else {
+            return FALSE; /* uncased and not case-ignorable */
+        }
+    }
+
+    return FALSE; /* not followed by cased letter */
+}
+
+/* Is preceded by Soft_Dotted character with no intervening cc=230 ? */
+static UBool
+isPrecededBySoftDotted(const UCaseProps *csp, UCaseContextIterator *iter, void *context) {
+    UChar32 c;
+    int32_t dotType;
+    int8_t dir;
+
+    if(iter==NULL) {
+        return FALSE;
+    }
+
+    for(dir=-1; (c=iter(context, dir))>=0; dir=0) {
+        dotType=getDotType(csp, c);
+        if(dotType==UCASE_SOFT_DOTTED) {
+            return TRUE; /* preceded by TYPE_i */
+        } else if(dotType!=UCASE_OTHER_ACCENT) {
+            return FALSE; /* preceded by different base character (not TYPE_i), or intervening cc==230 */
+        }
+    }
+
+    return FALSE; /* not preceded by TYPE_i */
+}
+
+/*
+ * See Jitterbug 2344:
+ * The condition After_I for Turkic-lowercasing of U+0307 combining dot above
+ * is checked in ICU 2.0, 2.1, 2.6 but was not in 2.2 & 2.4 because
+ * we made those releases compatible with Unicode 3.2 which had not fixed
+ * a related bug in SpecialCasing.txt.
+ *
+ * From the Jitterbug 2344 text:
+ * ... this bug is listed as a Unicode erratum
+ * from 2002-10-31 at http://www.unicode.org/uni2errata/UnicodeErrata.html
+ * <quote>
+ * There are two errors in SpecialCasing.txt.
+ * 1. Missing semicolons on two lines. ... [irrelevant for ICU]
+ * 2. An incorrect context definition. Correct as follows:
+ * < 0307; ; 0307; 0307; tr After_Soft_Dotted; # COMBINING DOT ABOVE
+ * < 0307; ; 0307; 0307; az After_Soft_Dotted; # COMBINING DOT ABOVE
+ * ---
+ * > 0307; ; 0307; 0307; tr After_I; # COMBINING DOT ABOVE
+ * > 0307; ; 0307; 0307; az After_I; # COMBINING DOT ABOVE
+ * where the context After_I is defined as:
+ * The last preceding base character was an uppercase I, and there is no
+ * intervening combining character class 230 (ABOVE).
+ * </quote>
+ *
+ * Note that SpecialCasing.txt even in Unicode 3.2 described the condition as:
+ *
+ * # When lowercasing, remove dot_above in the sequence I + dot_above, which will turn into i.
+ * # This matches the behavior of the canonically equivalent I-dot_above
+ *
+ * See also the description in this place in older versions of uchar.c (revision 1.100).
+ *
+ * Markus W. Scherer 2003-feb-15
+ */
+
+/* Is preceded by base character 'I' with no intervening cc=230 ? */
+static UBool
+isPrecededBy_I(const UCaseProps *csp, UCaseContextIterator *iter, void *context) {
+    UChar32 c;
+    int32_t dotType;
+    int8_t dir;
+
+    if(iter==NULL) {
+        return FALSE;
+    }
+
+    for(dir=-1; (c=iter(context, dir))>=0; dir=0) {
+        if(c==0x49) {
+            return TRUE; /* preceded by I */
+        }
+        dotType=getDotType(csp, c);
+        if(dotType!=UCASE_OTHER_ACCENT) {
+            return FALSE; /* preceded by different base character (not I), or intervening cc==230 */
+        }
+    }
+
+    return FALSE; /* not preceded by I */
+}
+
+/* Is followed by one or more cc==230 ? */
+static UBool
+isFollowedByMoreAbove(const UCaseProps *csp, UCaseContextIterator *iter, void *context) {
+    UChar32 c;
+    int32_t dotType;
+    int8_t dir;
+
+    if(iter==NULL) {
+        return FALSE;
+    }
+
+    for(dir=1; (c=iter(context, dir))>=0; dir=0) {
+        dotType=getDotType(csp, c);
+        if(dotType==UCASE_ABOVE) {
+            return TRUE; /* at least one cc==230 following */
+        } else if(dotType!=UCASE_OTHER_ACCENT) {
+            return FALSE; /* next base character, no more cc==230 following */
+        }
+    }
+
+    return FALSE; /* no more cc==230 following */
+}
+
+/* Is followed by a dot above (without cc==230 in between) ? */
+static UBool
+isFollowedByDotAbove(const UCaseProps *csp, UCaseContextIterator *iter, void *context) {
+    UChar32 c;
+    int32_t dotType;
+    int8_t dir;
+
+    if(iter==NULL) {
+        return FALSE;
+    }
+
+    for(dir=1; (c=iter(context, dir))>=0; dir=0) {
+        if(c==0x307) {
+            return TRUE;
+        }
+        dotType=getDotType(csp, c);
+        if(dotType!=UCASE_OTHER_ACCENT) {
+            return FALSE; /* next base character or cc==230 in between */
+        }
+    }
+
+    return FALSE; /* no dot above following */
+}
+
+U_CAPI int32_t U_EXPORT2
+ucase_toFullLower(const UCaseProps *csp, UChar32 c,
+                  UCaseContextIterator *iter, void *context,
+                  const UChar **pString,
+                  const char *locale, int32_t *locCache)
+{
+    UChar32 result=c;
+    uint16_t props=UTRIE2_GET16(&csp->trie, c);
+    if(!PROPS_HAS_EXCEPTION(props)) {
+        if(UCASE_GET_TYPE(props)>=UCASE_UPPER) {
+            result=c+UCASE_GET_DELTA(props);
+        }
+    } else {
+        const uint16_t *pe=GET_EXCEPTIONS(csp, props), *pe2;
+        uint16_t excWord=*pe++;
+        int32_t full;
+
+        pe2=pe;
+
+        if(excWord&UCASE_EXC_CONDITIONAL_SPECIAL) {
+            /* use hardcoded conditions and mappings */
+            int32_t loc=ucase_getCaseLocale(locale, locCache);
+
+            /*
+             * Test for conditional mappings first
+             *   (otherwise the unconditional default mappings are always taken),
+             * then test for characters that have unconditional mappings in SpecialCasing.txt,
+             * then get the UnicodeData.txt mappings.
+             */
+            if( loc==UCASE_LOC_LITHUANIAN &&
+                    /* base characters, find accents above */
+                    (((c==0x49 || c==0x4a || c==0x12e) &&
+                        isFollowedByMoreAbove(csp, iter, context)) ||
+                    /* precomposed with accent above, no need to find one */
+                    (c==0xcc || c==0xcd || c==0x128))
+            ) {
+                /*
+                    # Lithuanian
+
+                    # Lithuanian retains the dot in a lowercase i when followed by accents.
+
+                    # Introduce an explicit dot above when lowercasing capital I's and J's
+                    # whenever there are more accents above.
+                    # (of the accents used in Lithuanian: grave, acute, tilde above, and ogonek)
+
+                    0049; 0069 0307; 0049; 0049; lt More_Above; # LATIN CAPITAL LETTER I
+                    004A; 006A 0307; 004A; 004A; lt More_Above; # LATIN CAPITAL LETTER J
+                    012E; 012F 0307; 012E; 012E; lt More_Above; # LATIN CAPITAL LETTER I WITH OGONEK
+                    00CC; 0069 0307 0300; 00CC; 00CC; lt; # LATIN CAPITAL LETTER I WITH GRAVE
+                    00CD; 0069 0307 0301; 00CD; 00CD; lt; # LATIN CAPITAL LETTER I WITH ACUTE
+                    0128; 0069 0307 0303; 0128; 0128; lt; # LATIN CAPITAL LETTER I WITH TILDE
+                 */
+                switch(c) {
+                case 0x49:  /* LATIN CAPITAL LETTER I */
+                    *pString=iDot;
+                    return 2;
+                case 0x4a:  /* LATIN CAPITAL LETTER J */
+                    *pString=jDot;
+                    return 2;
+                case 0x12e: /* LATIN CAPITAL LETTER I WITH OGONEK */
+                    *pString=iOgonekDot;
+                    return 2;
+                case 0xcc:  /* LATIN CAPITAL LETTER I WITH GRAVE */
+                    *pString=iDotGrave;
+                    return 3;
+                case 0xcd:  /* LATIN CAPITAL LETTER I WITH ACUTE */
+                    *pString=iDotAcute;
+                    return 3;
+                case 0x128: /* LATIN CAPITAL LETTER I WITH TILDE */
+                    *pString=iDotTilde;
+                    return 3;
+                default:
+                    return 0; /* will not occur */
+                }
+            /* # Turkish and Azeri */
+            } else if(loc==UCASE_LOC_TURKISH && c==0x130) {
+                /*
+                    # I and i-dotless; I-dot and i are case pairs in Turkish and Azeri
+                    # The following rules handle those cases.
+
+                    0130; 0069; 0130; 0130; tr # LATIN CAPITAL LETTER I WITH DOT ABOVE
+                    0130; 0069; 0130; 0130; az # LATIN CAPITAL LETTER I WITH DOT ABOVE
+                 */
+                return 0x69;
+            } else if(loc==UCASE_LOC_TURKISH && c==0x307 && isPrecededBy_I(csp, iter, context)) {
+                /*
+                    # When lowercasing, remove dot_above in the sequence I + dot_above, which will turn into i.
+                    # This matches the behavior of the canonically equivalent I-dot_above
+
+                    0307; ; 0307; 0307; tr After_I; # COMBINING DOT ABOVE
+                    0307; ; 0307; 0307; az After_I; # COMBINING DOT ABOVE
+                 */
+                return 0; /* remove the dot (continue without output) */
+            } else if(loc==UCASE_LOC_TURKISH && c==0x49 && !isFollowedByDotAbove(csp, iter, context)) {
+                /*
+                    # When lowercasing, unless an I is before a dot_above, it turns into a dotless i.
+
+                    0049; 0131; 0049; 0049; tr Not_Before_Dot; # LATIN CAPITAL LETTER I
+                    0049; 0131; 0049; 0049; az Not_Before_Dot; # LATIN CAPITAL LETTER I
+                 */
+                return 0x131;
+            } else if(c==0x130) {
+                /*
+                    # Preserve canonical equivalence for I with dot. Turkic is handled below.
+
+                    0130; 0069 0307; 0130; 0130; # LATIN CAPITAL LETTER I WITH DOT ABOVE
+                 */
+                *pString=iDot;
+                return 2;
+            } else if(  c==0x3a3 &&
+                        !isFollowedByCasedLetter(csp, iter, context, 1) &&
+                        isFollowedByCasedLetter(csp, iter, context, -1) /* -1=preceded */
+            ) {
+                /* greek capital sigma maps depending on surrounding cased letters (see SpecialCasing.txt) */
+                /*
+                    # Special case for final form of sigma
+
+                    03A3; 03C2; 03A3; 03A3; Final_Sigma; # GREEK CAPITAL LETTER SIGMA
+                 */
+                return 0x3c2; /* greek small final sigma */
+            } else {
+                /* no known conditional special case mapping, use a normal mapping */
+            }
+        } else if(HAS_SLOT(excWord, UCASE_EXC_FULL_MAPPINGS)) {
+            GET_SLOT_VALUE(excWord, UCASE_EXC_FULL_MAPPINGS, pe, full);
+            full&=UCASE_FULL_LOWER;
+            if(full!=0) {
+                /* set the output pointer to the lowercase mapping */
+                *pString=pe+1;
+
+                /* return the string length */
+                return full;
+            }
+        }
+
+        if(HAS_SLOT(excWord, UCASE_EXC_LOWER)) {
+            GET_SLOT_VALUE(excWord, UCASE_EXC_LOWER, pe2, result);
+        }
+    }
+
+    return (result==c) ? ~result : result;
+}
+
+/* internal */
+static int32_t
+toUpperOrTitle(const UCaseProps *csp, UChar32 c,
+               UCaseContextIterator *iter, void *context,
+               const UChar **pString,
+               const char *locale, int32_t *locCache,
+               UBool upperNotTitle) {
+    UChar32 result=c;
+    uint16_t props=UTRIE2_GET16(&csp->trie, c);
+    if(!PROPS_HAS_EXCEPTION(props)) {
+        if(UCASE_GET_TYPE(props)==UCASE_LOWER) {
+            result=c+UCASE_GET_DELTA(props);
+        }
+    } else {
+        const uint16_t *pe=GET_EXCEPTIONS(csp, props), *pe2;
+        uint16_t excWord=*pe++;
+        int32_t full, idx;
+
+        pe2=pe;
+
+        if(excWord&UCASE_EXC_CONDITIONAL_SPECIAL) {
+            /* use hardcoded conditions and mappings */
+            int32_t loc=ucase_getCaseLocale(locale, locCache);
+
+            if(loc==UCASE_LOC_TURKISH && c==0x69) {
+                /*
+                    # Turkish and Azeri
+
+                    # I and i-dotless; I-dot and i are case pairs in Turkish and Azeri
+                    # The following rules handle those cases.
+
+                    # When uppercasing, i turns into a dotted capital I
+
+                    0069; 0069; 0130; 0130; tr; # LATIN SMALL LETTER I
+                    0069; 0069; 0130; 0130; az; # LATIN SMALL LETTER I
+                */
+                return 0x130;
+            } else if(loc==UCASE_LOC_LITHUANIAN && c==0x307 && isPrecededBySoftDotted(csp, iter, context)) {
+                /*
+                    # Lithuanian
+
+                    # Lithuanian retains the dot in a lowercase i when followed by accents.
+
+                    # Remove DOT ABOVE after "i" with upper or titlecase
+
+                    0307; 0307; ; ; lt After_Soft_Dotted; # COMBINING DOT ABOVE
+                 */
+                return 0; /* remove the dot (continue without output) */
+            } else {
+                /* no known conditional special case mapping, use a normal mapping */
+            }
+        } else if(HAS_SLOT(excWord, UCASE_EXC_FULL_MAPPINGS)) {
+            GET_SLOT_VALUE(excWord, UCASE_EXC_FULL_MAPPINGS, pe, full);
+
+            /* start of full case mapping strings */
+            ++pe;
+
+            /* skip the lowercase and case-folding result strings */
+            pe+=full&UCASE_FULL_LOWER;
+            full>>=4;
+            pe+=full&0xf;
+            full>>=4;
+
+            if(upperNotTitle) {
+                full&=0xf;
+            } else {
+                /* skip the uppercase result string */
+                pe+=full&0xf;
+                full=(full>>4)&0xf;
+            }
+
+            if(full!=0) {
+                /* set the output pointer to the result string */
+                *pString=pe;
+
+                /* return the string length */
+                return full;
+            }
+        }
+
+        if(!upperNotTitle && HAS_SLOT(excWord, UCASE_EXC_TITLE)) {
+            idx=UCASE_EXC_TITLE;
+        } else if(HAS_SLOT(excWord, UCASE_EXC_UPPER)) {
+            /* here, titlecase is same as uppercase */
+            idx=UCASE_EXC_UPPER;
+        } else {
+            return ~c;
+        }
+        GET_SLOT_VALUE(excWord, idx, pe2, result);
+    }
+
+    return (result==c) ? ~result : result;
+}
+
+U_CAPI int32_t U_EXPORT2
+ucase_toFullUpper(const UCaseProps *csp, UChar32 c,
+                  UCaseContextIterator *iter, void *context,
+                  const UChar **pString,
+                  const char *locale, int32_t *locCache) {
+    return toUpperOrTitle(csp, c, iter, context, pString, locale, locCache, TRUE);
+}
+
+U_CAPI int32_t U_EXPORT2
+ucase_toFullTitle(const UCaseProps *csp, UChar32 c,
+                  UCaseContextIterator *iter, void *context,
+                  const UChar **pString,
+                  const char *locale, int32_t *locCache) {
+    return toUpperOrTitle(csp, c, iter, context, pString, locale, locCache, FALSE);
+}
+
+/* case folding ------------------------------------------------------------- */
+
+/*
+ * Case folding is similar to lowercasing.
+ * The result may be a simple mapping, i.e., a single code point, or
+ * a full mapping, i.e., a string.
+ * If the case folding for a code point is the same as its simple (1:1) lowercase mapping,
+ * then only the lowercase mapping is stored.
+ *
+ * Some special cases are hardcoded because their conditions cannot be
+ * parsed and processed from CaseFolding.txt.
+ *
+ * Unicode 3.2 CaseFolding.txt specifies for its status field:
+
+# C: common case folding, common mappings shared by both simple and full mappings.
+# F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+# S: simple case folding, mappings to single characters where different from F.
+# T: special case for uppercase I and dotted uppercase I
+#    - For non-Turkic languages, this mapping is normally not used.
+#    - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+#
+# Usage:
+#  A. To do a simple case folding, use the mappings with status C + S.
+#  B. To do a full case folding, use the mappings with status C + F.
+#
+#    The mappings with status T can be used or omitted depending on the desired case-folding
+#    behavior. (The default option is to exclude them.)
+
+ * Unicode 3.2 has 'T' mappings as follows:
+
+0049; T; 0131; # LATIN CAPITAL LETTER I
+0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE
+
+ * while the default mappings for these code points are:
+
+0049; C; 0069; # LATIN CAPITAL LETTER I
+0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE
+
+ * U+0130 has no simple case folding (simple-case-folds to itself).
+ */
+
+/* return the simple case folding mapping for c */
+U_CAPI UChar32 U_EXPORT2
+ucase_fold(const UCaseProps *csp, UChar32 c, uint32_t options) {
+    uint16_t props=UTRIE2_GET16(&csp->trie, c);
+    if(!PROPS_HAS_EXCEPTION(props)) {
+        if(UCASE_GET_TYPE(props)>=UCASE_UPPER) {
+            c+=UCASE_GET_DELTA(props);
+        }
+    } else {
+        const uint16_t *pe=GET_EXCEPTIONS(csp, props);
+        uint16_t excWord=*pe++;
+        int32_t idx;
+        if(excWord&UCASE_EXC_CONDITIONAL_FOLD) {
+            /* special case folding mappings, hardcoded */
+            if((options&_FOLD_CASE_OPTIONS_MASK)==U_FOLD_CASE_DEFAULT) {
+                /* default mappings */
+                if(c==0x49) {
+                    /* 0049; C; 0069; # LATIN CAPITAL LETTER I */
+                    return 0x69;
+                } else if(c==0x130) {
+                    /* no simple case folding for U+0130 */
+                    return c;
+                }
+            } else {
+                /* Turkic mappings */
+                if(c==0x49) {
+                    /* 0049; T; 0131; # LATIN CAPITAL LETTER I */
+                    return 0x131;
+                } else if(c==0x130) {
+                    /* 0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE */
+                    return 0x69;
+                }
+            }
+        }
+        if(HAS_SLOT(excWord, UCASE_EXC_FOLD)) {
+            idx=UCASE_EXC_FOLD;
+        } else if(HAS_SLOT(excWord, UCASE_EXC_LOWER)) {
+            idx=UCASE_EXC_LOWER;
+        } else {
+            return c;
+        }
+        GET_SLOT_VALUE(excWord, idx, pe, c);
+    }
+    return c;
+}
+
+/*
+ * Issue for canonical caseless match (UAX #21):
+ * Turkic casefolding (using "T" mappings in CaseFolding.txt) does not preserve
+ * canonical equivalence, unlike default-option casefolding.
+ * For example, I-grave and I + grave fold to strings that are not canonically
+ * equivalent.
+ * For more details, see the comment in unorm_compare() in unorm.cpp
+ * and the intermediate prototype changes for Jitterbug 2021.
+ * (For example, revision 1.104 of uchar.c and 1.4 of CaseFolding.txt.)
+ *
+ * This did not get fixed because it appears that it is not possible to fix
+ * it for uppercase and lowercase characters (I-grave vs. i-grave)
+ * together in a way that they still fold to common result strings.
+ */
+
+U_CAPI int32_t U_EXPORT2
+ucase_toFullFolding(const UCaseProps *csp, UChar32 c,
+                    const UChar **pString,
+                    uint32_t options)
+{
+    UChar32 result=c;
+    uint16_t props=UTRIE2_GET16(&csp->trie, c);
+    if(!PROPS_HAS_EXCEPTION(props)) {
+        if(UCASE_GET_TYPE(props)>=UCASE_UPPER) {
+            result=c+UCASE_GET_DELTA(props);
+        }
+    } else {
+        const uint16_t *pe=GET_EXCEPTIONS(csp, props), *pe2;
+        uint16_t excWord=*pe++;
+        int32_t full, idx;
+
+        pe2=pe;
+
+        if(excWord&UCASE_EXC_CONDITIONAL_FOLD) {
+            /* use hardcoded conditions and mappings */
+            if((options&_FOLD_CASE_OPTIONS_MASK)==U_FOLD_CASE_DEFAULT) {
+                /* default mappings */
+                if(c==0x49) {
+                    /* 0049; C; 0069; # LATIN CAPITAL LETTER I */
+                    return 0x69;
+                } else if(c==0x130) {
+                    /* 0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE */
+                    *pString=iDot;
+                    return 2;
+                }
+            } else {
+                /* Turkic mappings */
+                if(c==0x49) {
+                    /* 0049; T; 0131; # LATIN CAPITAL LETTER I */
+                    return 0x131;
+                } else if(c==0x130) {
+                    /* 0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE */
+                    return 0x69;
+                }
+            }
+        } else if(HAS_SLOT(excWord, UCASE_EXC_FULL_MAPPINGS)) {
+            GET_SLOT_VALUE(excWord, UCASE_EXC_FULL_MAPPINGS, pe, full);
+
+            /* start of full case mapping strings */
+            ++pe;
+
+            /* skip the lowercase result string */
+            pe+=full&UCASE_FULL_LOWER;
+            full=(full>>4)&0xf;
+
+            if(full!=0) {
+                /* set the output pointer to the result string */
+                *pString=pe;
+
+                /* return the string length */
+                return full;
+            }
+        }
+
+        if(HAS_SLOT(excWord, UCASE_EXC_FOLD)) {
+            idx=UCASE_EXC_FOLD;
+        } else if(HAS_SLOT(excWord, UCASE_EXC_LOWER)) {
+            idx=UCASE_EXC_LOWER;
+        } else {
+            return ~c;
+        }
+        GET_SLOT_VALUE(excWord, idx, pe2, result);
+    }
+
+    return (result==c) ? ~result : result;
+}
+
+/* case mapping properties API ---------------------------------------------- */
+
+/* get the UCaseProps singleton, or else its dummy, once and for all */
+#if !UCASE_HARDCODE_DATA
+static const UCaseProps *
+getCaseProps() {
+    /*
+     * This lazy intialization with double-checked locking (without mutex protection for
+     * the initial check) is transiently unsafe under certain circumstances.
+     * Check the readme and use u_init() if necessary.
+     */
+
+    /* the initial check is performed by the GET_CASE_PROPS() macro */
+    const UCaseProps *csp;
+    UErrorCode errorCode=U_ZERO_ERROR;
+
+    csp=ucase_getSingleton(&errorCode);
+    if(U_FAILURE(errorCode)) {
+        errorCode=U_ZERO_ERROR;
+        csp=ucase_getDummy(&errorCode);
+        if(U_FAILURE(errorCode)) {
+            return NULL;
+        }
+    }
+
+    return csp;
+}
+#endif
+
+/*
+ * In ICU 3.0, most Unicode properties were loaded from uprops.icu.
+ * ICU 3.2 adds ucase.icu for case mapping properties.
+ * ICU 3.4 adds ubidi.icu for bidi/shaping properties and
+ * removes case/bidi/shaping properties from uprops.icu.
+ *
+ * Loading of uprops.icu was never mutex-protected and required u_init()
+ * for thread safety.
+ * In order to maintain performance for all such properties,
+ * ucase.icu and ubidi.icu are loaded lazily, without mutexing.
+ * u_init() will try to load them for thread safety,
+ * but u_init() will not fail if they are missing.
+ *
+ * uchar.c maintains a tri-state flag for (not loaded/loaded/failed to load)
+ * and an error code for load failure.
+ * Instead, here we try to load at most once.
+ * If it works, we use the resulting singleton object.
+ * If it fails, then we get a dummy object, which always works unless
+ * we are seriously out of memory.
+ * After the first try, we have a never-changing pointer to either the
+ * real singleton or the dummy.
+ *
+ * This method is used in Unicode properties APIs (uchar.h) that
+ * do not have a service object and also do not have an error code parameter.
+ * Other API implementations get the singleton themselves
+ * (with mutexing), store it in the service object, and report errors.
+ *
+ * TODO:  Remove this support for non-hardcoded data.  u_init() is publicly
+ *        advertised as not being required for thread safety, we cannot
+ *        revert to unsafe data loading.
+ */
+#if !UCASE_HARDCODE_DATA
+#define GET_CASE_PROPS() (gCsp!=NULL ? gCsp : getCaseProps())
+#else
+#define GET_CASE_PROPS() &ucase_props_singleton
+#endif
+
+/* public API (see uchar.h) */
+
+U_CAPI UBool U_EXPORT2
+u_isULowercase(UChar32 c) {
+    return (UBool)(UCASE_LOWER==ucase_getType(GET_CASE_PROPS(), c));
+}
+
+U_CAPI UBool U_EXPORT2
+u_isUUppercase(UChar32 c) {
+    return (UBool)(UCASE_UPPER==ucase_getType(GET_CASE_PROPS(), c));
+}
+
+/* Transforms the Unicode character to its lower case equivalent.*/
+U_CAPI UChar32 U_EXPORT2
+u_tolower(UChar32 c) {
+    return ucase_tolower(GET_CASE_PROPS(), c);
+}
+    
+/* Transforms the Unicode character to its upper case equivalent.*/
+U_CAPI UChar32 U_EXPORT2
+u_toupper(UChar32 c) {
+    return ucase_toupper(GET_CASE_PROPS(), c);
+}
+
+/* Transforms the Unicode character to its title case equivalent.*/
+U_CAPI UChar32 U_EXPORT2
+u_totitle(UChar32 c) {
+    return ucase_totitle(GET_CASE_PROPS(), c);
+}
+
+/* return the simple case folding mapping for c */
+U_CAPI UChar32 U_EXPORT2
+u_foldCase(UChar32 c, uint32_t options) {
+    return ucase_fold(GET_CASE_PROPS(), c, options);
+}
+
+U_CFUNC int32_t U_EXPORT2
+ucase_hasBinaryProperty(UChar32 c, UProperty which) {
+    /* case mapping properties */
+    const UChar *resultString;
+    int32_t locCache;
+    const UCaseProps *csp=GET_CASE_PROPS();
+    if(csp==NULL) {
+        return FALSE;
+    }
+    switch(which) {
+    case UCHAR_LOWERCASE:
+        return (UBool)(UCASE_LOWER==ucase_getType(csp, c));
+    case UCHAR_UPPERCASE:
+        return (UBool)(UCASE_UPPER==ucase_getType(csp, c));
+    case UCHAR_SOFT_DOTTED:
+        return ucase_isSoftDotted(csp, c);
+    case UCHAR_CASE_SENSITIVE:
+        return ucase_isCaseSensitive(csp, c);
+    case UCHAR_CASED:
+        return (UBool)(UCASE_NONE!=ucase_getType(csp, c));
+    case UCHAR_CASE_IGNORABLE:
+        return (UBool)(ucase_getTypeOrIgnorable(csp, c)>>2);
+    /*
+     * Note: The following Changes_When_Xyz are defined as testing whether
+     * the NFD form of the input changes when Xyz-case-mapped.
+     * However, this simpler implementation of these properties,
+     * ignoring NFD, passes the tests.
+     * The implementation needs to be changed if the tests start failing.
+     * When that happens, optimizations should be used to work with the
+     * per-single-code point ucase_toFullXyz() functions unless
+     * the NFD form has more than one code point,
+     * and the property starts set needs to be the union of the
+     * start sets for normalization and case mappings.
+     */
+    case UCHAR_CHANGES_WHEN_LOWERCASED:
+        locCache=UCASE_LOC_ROOT;
+        return (UBool)(ucase_toFullLower(csp, c, NULL, NULL, &resultString, "", &locCache)>=0);
+    case UCHAR_CHANGES_WHEN_UPPERCASED:
+        locCache=UCASE_LOC_ROOT;
+        return (UBool)(ucase_toFullUpper(csp, c, NULL, NULL, &resultString, "", &locCache)>=0);
+    case UCHAR_CHANGES_WHEN_TITLECASED:
+        locCache=UCASE_LOC_ROOT;
+        return (UBool)(ucase_toFullTitle(csp, c, NULL, NULL, &resultString, "", &locCache)>=0);
+    /* case UCHAR_CHANGES_WHEN_CASEFOLDED: -- in uprops.c */
+    case UCHAR_CHANGES_WHEN_CASEMAPPED:
+        locCache=UCASE_LOC_ROOT;
+        return (UBool)(
+            ucase_toFullLower(csp, c, NULL, NULL, &resultString, "", &locCache)>=0 ||
+            ucase_toFullUpper(csp, c, NULL, NULL, &resultString, "", &locCache)>=0 ||
+            ucase_toFullTitle(csp, c, NULL, NULL, &resultString, "", &locCache)>=0);
+    default:
+        return FALSE;
+    }
+}
diff --git a/icu/source/common/ucase.h b/icu/source/common/ucase.h
new file mode 100644
index 0000000..1a748f4
--- /dev/null
+++ b/icu/source/common/ucase.h
@@ -0,0 +1,391 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2004-2009, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  ucase.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2004aug30
+*   created by: Markus W. Scherer
+*
+*   Low-level Unicode character/string case mapping code.
+*/
+
+#ifndef __UCASE_H__
+#define __UCASE_H__
+
+#include "unicode/utypes.h"
+#include "unicode/uset.h"
+#include "uset_imp.h"
+#include "udataswp.h"
+
+U_CDECL_BEGIN
+
+/* library API -------------------------------------------------------------- */
+
+struct UCaseProps;
+typedef struct UCaseProps UCaseProps;
+
+U_CAPI UCaseProps * U_EXPORT2
+ucase_open(UErrorCode *pErrorCode);
+
+U_CAPI UCaseProps * U_EXPORT2
+ucase_openBinary(const uint8_t *bin, int32_t length, UErrorCode *pErrorCode);
+
+U_CAPI void U_EXPORT2
+ucase_close(UCaseProps *csp);
+
+
+U_CAPI const UCaseProps * U_EXPORT2
+ucase_getSingleton(UErrorCode *pErrorCode);
+
+#define UCASE_HARDCODE_DATA 1
+
+#if !UCASE_HARDCODE_DATA
+/**
+ * Get a singleton dummy object, one that works with no real data.
+ * This can be used when the real data is not available.
+ * Using the dummy can reduce checks for available data after an initial failure.
+ */
+U_CAPI const UCaseProps * U_EXPORT2
+ucase_getDummy(UErrorCode *pErrorCode);
+#endif
+
+
+U_CAPI int32_t U_EXPORT2
+ucase_swap(const UDataSwapper *ds,
+           const void *inData, int32_t length, void *outData,
+           UErrorCode *pErrorCode);
+
+U_CFUNC void U_EXPORT2
+ucase_addPropertyStarts(const UCaseProps *csp, const USetAdder *sa, UErrorCode *pErrorCode);
+
+/**
+ * Requires non-NULL locale ID but otherwise does the equivalent of
+ * checking for language codes as if uloc_getLanguage() were called:
+ * Accepts both 2- and 3-letter codes and accepts case variants.
+ */
+U_CFUNC int32_t
+ucase_getCaseLocale(const char *locale, int32_t *locCache);
+
+/* Casing locale types for ucase_getCaseLocale */
+enum {
+    UCASE_LOC_UNKNOWN,
+    UCASE_LOC_ROOT,
+    UCASE_LOC_TURKISH,
+    UCASE_LOC_LITHUANIAN,
+    UCASE_LOC_DUTCH
+};
+
+/**
+ * Bit mask for getting just the options from a string compare options word
+ * that are relevant for case-insensitive string comparison.
+ * See uchar.h. Also include _STRNCMP_STYLE and U_COMPARE_CODE_POINT_ORDER.
+ * @internal
+ */
+#define _STRCASECMP_OPTIONS_MASK 0xffff
+
+/**
+ * Bit mask for getting just the options from a string compare options word
+ * that are relevant for case folding (of a single string or code point).
+ * See uchar.h.
+ * @internal
+ */
+#define _FOLD_CASE_OPTIONS_MASK 0xff
+
+/* single-code point functions */
+
+U_CAPI UChar32 U_EXPORT2
+ucase_tolower(const UCaseProps *csp, UChar32 c);
+
+U_CAPI UChar32 U_EXPORT2
+ucase_toupper(const UCaseProps *csp, UChar32 c);
+
+U_CAPI UChar32 U_EXPORT2
+ucase_totitle(const UCaseProps *csp, UChar32 c);
+
+U_CAPI UChar32 U_EXPORT2
+ucase_fold(const UCaseProps *csp, UChar32 c, uint32_t options);
+
+/**
+ * Adds all simple case mappings and the full case folding for c to sa,
+ * and also adds special case closure mappings.
+ * c itself is not added.
+ * For example, the mappings
+ * - for s include long s
+ * - for sharp s include ss
+ * - for k include the Kelvin sign
+ */
+U_CFUNC void U_EXPORT2
+ucase_addCaseClosure(const UCaseProps *csp, UChar32 c, const USetAdder *sa);
+
+/**
+ * Maps the string to single code points and adds the associated case closure
+ * mappings.
+ * The string is mapped to code points if it is their full case folding string.
+ * In other words, this performs a reverse full case folding and then
+ * adds the case closure items of the resulting code points.
+ * If the string is found and its closure applied, then
+ * the string itself is added as well as part of its code points' closure.
+ * It must be length>=0.
+ *
+ * @return TRUE if the string was found
+ */
+U_CFUNC UBool U_EXPORT2
+ucase_addStringCaseClosure(const UCaseProps *csp, const UChar *s, int32_t length, const USetAdder *sa);
+
+/** @return UCASE_NONE, UCASE_LOWER, UCASE_UPPER, UCASE_TITLE */
+U_CAPI int32_t U_EXPORT2
+ucase_getType(const UCaseProps *csp, UChar32 c);
+
+/** @return same as ucase_getType(), or <0 if c is case-ignorable */
+U_CAPI int32_t U_EXPORT2
+ucase_getTypeOrIgnorable(const UCaseProps *csp, UChar32 c);
+
+U_CAPI UBool U_EXPORT2
+ucase_isSoftDotted(const UCaseProps *csp, UChar32 c);
+
+U_CAPI UBool U_EXPORT2
+ucase_isCaseSensitive(const UCaseProps *csp, UChar32 c);
+
+/* string case mapping functions */
+
+/**
+ * Iterator function for string case mappings, which need to look at the
+ * context (surrounding text) of a given character for conditional mappings.
+ *
+ * The iterator only needs to go backward or forward away from the
+ * character in question. It does not use any indexes on this interface.
+ * It does not support random access or an arbitrary change of
+ * iteration direction.
+ *
+ * The code point being case-mapped itself is never returned by
+ * this iterator.
+ *
+ * @param context A pointer to the iterator's working data.
+ * @param dir If <0 then start iterating backward from the character;
+ *            if >0 then start iterating forward from the character;
+ *            if 0 then continue iterating in the current direction.
+ * @return Next code point, or <0 when the iteration is done.
+ */
+typedef UChar32 U_CALLCONV
+UCaseContextIterator(void *context, int8_t dir);
+
+/**
+ * Sample struct which may be used by some implementations of
+ * UCaseContextIterator.
+ */
+struct UCaseContext {
+    void *p;
+    int32_t start, index, limit;
+    int32_t cpStart, cpLimit;
+    int8_t dir;
+    int8_t b1, b2, b3;
+};
+typedef struct UCaseContext UCaseContext;
+
+enum {
+    /**
+     * For string case mappings, a single character (a code point) is mapped
+     * either to itself (in which case in-place mapping functions do nothing),
+     * or to another single code point, or to a string.
+     * Aside from the string contents, these are indicated with a single int32_t
+     * value as follows:
+     *
+     * Mapping to self: Negative values (~self instead of -self to support U+0000)
+     *
+     * Mapping to another code point: Positive values >UCASE_MAX_STRING_LENGTH
+     *
+     * Mapping to a string: The string length (0..UCASE_MAX_STRING_LENGTH) is
+     * returned. Note that the string result may indeed have zero length.
+     */
+    UCASE_MAX_STRING_LENGTH=0x1f
+};
+
+/**
+ * Get the full lowercase mapping for c.
+ *
+ * @param csp Case mapping properties.
+ * @param c Character to be mapped.
+ * @param iter Character iterator, used for context-sensitive mappings.
+ *             See UCaseContextIterator for details.
+ *             If iter==NULL then a context-independent result is returned.
+ * @param context Pointer to be passed into iter.
+ * @param pString If the mapping result is a string, then the pointer is
+ *                written to *pString.
+ * @param locale Locale ID for locale-dependent mappings.
+ * @param locCache Initialize to 0; may be used to cache the result of parsing
+ *                 the locale ID for subsequent calls.
+ *                 Can be NULL.
+ * @return Output code point or string length, see UCASE_MAX_STRING_LENGTH.
+ *
+ * @see UCaseContextIterator
+ * @see UCASE_MAX_STRING_LENGTH
+ * @internal
+ */
+U_CAPI int32_t U_EXPORT2
+ucase_toFullLower(const UCaseProps *csp, UChar32 c,
+                  UCaseContextIterator *iter, void *context,
+                  const UChar **pString,
+                  const char *locale, int32_t *locCache);
+
+U_CAPI int32_t U_EXPORT2
+ucase_toFullUpper(const UCaseProps *csp, UChar32 c,
+                  UCaseContextIterator *iter, void *context,
+                  const UChar **pString,
+                  const char *locale, int32_t *locCache);
+
+U_CAPI int32_t U_EXPORT2
+ucase_toFullTitle(const UCaseProps *csp, UChar32 c,
+                  UCaseContextIterator *iter, void *context,
+                  const UChar **pString,
+                  const char *locale, int32_t *locCache);
+
+U_CAPI int32_t U_EXPORT2
+ucase_toFullFolding(const UCaseProps *csp, UChar32 c,
+                    const UChar **pString,
+                    uint32_t options);
+
+U_CFUNC int32_t U_EXPORT2
+ucase_hasBinaryProperty(UChar32 c, UProperty which);
+
+
+U_CDECL_BEGIN
+
+/**
+ * @internal
+ */
+typedef int32_t U_CALLCONV
+UCaseMapFull(const UCaseProps *csp, UChar32 c,
+             UCaseContextIterator *iter, void *context,
+             const UChar **pString,
+             const char *locale, int32_t *locCache);
+
+U_CDECL_END
+
+/* file definitions --------------------------------------------------------- */
+
+#define UCASE_DATA_NAME "ucase"
+#define UCASE_DATA_TYPE "icu"
+
+/* format "cAsE" */
+#define UCASE_FMT_0 0x63
+#define UCASE_FMT_1 0x41
+#define UCASE_FMT_2 0x53
+#define UCASE_FMT_3 0x45
+
+/* indexes into indexes[] */
+enum {
+    UCASE_IX_INDEX_TOP,
+    UCASE_IX_LENGTH,
+    UCASE_IX_TRIE_SIZE,
+    UCASE_IX_EXC_LENGTH,
+    UCASE_IX_UNFOLD_LENGTH,
+
+    UCASE_IX_MAX_FULL_LENGTH=15,
+    UCASE_IX_TOP=16
+};
+
+/* definitions for 16-bit case properties word ------------------------------ */
+
+/* 2-bit constants for types of cased characters */
+#define UCASE_TYPE_MASK     3
+enum {
+    UCASE_NONE,
+    UCASE_LOWER,
+    UCASE_UPPER,
+    UCASE_TITLE
+};
+
+#define UCASE_GET_TYPE(props) ((props)&UCASE_TYPE_MASK)
+
+#define UCASE_SENSITIVE     4
+#define UCASE_EXCEPTION     8
+
+#define UCASE_DOT_MASK      0x30
+enum {
+    UCASE_NO_DOT=0,         /* normal characters with cc=0 */
+    UCASE_SOFT_DOTTED=0x10, /* soft-dotted characters with cc=0 */
+    UCASE_ABOVE=0x20,       /* "above" accents with cc=230 */
+    UCASE_OTHER_ACCENT=0x30 /* other accent character (0<cc!=230) */
+};
+
+/* no exception: bits 15..6 are a 10-bit signed case mapping delta */
+#define UCASE_DELTA_SHIFT   6
+#define UCASE_DELTA_MASK    0xffc0
+#define UCASE_MAX_DELTA     0x1ff
+#define UCASE_MIN_DELTA     (-UCASE_MAX_DELTA-1)
+
+#define UCASE_GET_DELTA(props) ((int16_t)(props)>>UCASE_DELTA_SHIFT)
+
+/* case-ignorable uses one of the delta bits, see gencase/store.c */
+#define UCASE_CASE_IGNORABLE 0x40
+
+/* exception: bits 15..4 are an unsigned 12-bit index into the exceptions array */
+#define UCASE_EXC_SHIFT     4
+#define UCASE_EXC_MASK      0xfff0
+#define UCASE_MAX_EXCEPTIONS 0x1000
+
+/* definitions for 16-bit main exceptions word ------------------------------ */
+
+/* first 8 bits indicate values in optional slots */
+enum {
+    UCASE_EXC_LOWER,
+    UCASE_EXC_FOLD,
+    UCASE_EXC_UPPER,
+    UCASE_EXC_TITLE,
+    UCASE_EXC_4,            /* reserved */
+    UCASE_EXC_5,            /* reserved */
+    UCASE_EXC_CLOSURE,
+    UCASE_EXC_FULL_MAPPINGS,
+    UCASE_EXC_ALL_SLOTS     /* one past the last slot */
+};
+
+/* each slot is 2 uint16_t instead of 1 */
+#define UCASE_EXC_DOUBLE_SLOTS      0x100
+
+/* reserved: exception bits 10..9 */
+
+#define UCASE_EXC_CASE_IGNORABLE        0x800
+
+/* UCASE_EXC_DOT_MASK=UCASE_DOT_MASK<<UCASE_EXC_DOT_SHIFT */
+#define UCASE_EXC_DOT_SHIFT     8
+
+/* normally stored in the main word, but pushed out for larger exception indexes */
+#define UCASE_EXC_DOT_MASK      0x3000
+enum {
+    UCASE_EXC_NO_DOT=0,
+    UCASE_EXC_SOFT_DOTTED=0x1000,
+    UCASE_EXC_ABOVE=0x2000,         /* "above" accents with cc=230 */
+    UCASE_EXC_OTHER_ACCENT=0x3000   /* other character (0<cc!=230) */
+};
+
+/* complex/conditional mappings */
+#define UCASE_EXC_CONDITIONAL_SPECIAL   0x4000
+#define UCASE_EXC_CONDITIONAL_FOLD      0x8000
+
+/* definitions for lengths word for full case mappings */
+#define UCASE_FULL_LOWER    0xf
+#define UCASE_FULL_FOLDING  0xf0
+#define UCASE_FULL_UPPER    0xf00
+#define UCASE_FULL_TITLE    0xf000
+
+/* maximum lengths */
+#define UCASE_FULL_MAPPINGS_MAX_LENGTH (4*0xf)
+#define UCASE_CLOSURE_MAX_LENGTH 0xf
+
+/* constants for reverse case folding ("unfold") data */
+enum {
+    UCASE_UNFOLD_ROWS,
+    UCASE_UNFOLD_ROW_WIDTH,
+    UCASE_UNFOLD_STRING_WIDTH
+};
+
+U_CDECL_END
+
+#endif
diff --git a/icu/source/common/ucase_props_data.c b/icu/source/common/ucase_props_data.c
new file mode 100644
index 0000000..675e8e4
--- /dev/null
+++ b/icu/source/common/ucase_props_data.c
@@ -0,0 +1,721 @@
+/*
+ * Copyright (C) 1999-2009, International Business Machines
+ * Corporation and others.  All Rights Reserved.
+ *
+ * file name: ucase_props_data.c
+ *
+ * machine-generated on: 2009-11-09
+ */
+
+static const UVersionInfo ucase_props_dataVersion={5,2,0,0};
+
+static const int32_t ucase_props_indexes[UCASE_IX_TOP]={0x10,0x4f24,0x41f0,0x508,0x172,0,0,0,0,0,0,0,0,0,0,3};
+
+static const uint16_t ucase_props_trieIndex[9160]={
+0x2c1,0x2c9,0x2d1,0x2d9,0x2e7,0x2ef,0x2f7,0x2ff,0x307,0x30f,0x316,0x31e,0x326,0x32e,0x336,0x33e,
+0x344,0x34c,0x354,0x35c,0x364,0x36c,0x374,0x37c,0x384,0x38c,0x394,0x39c,0x3a4,0x3ac,0x3b4,0x3bc,
+0x3c4,0x3cc,0x3d0,0x3d8,0x3e0,0x3e8,0x3f0,0x3f8,0x3f7,0x3ff,0x404,0x40c,0x413,0x41b,0x423,0x42b,
+0x433,0x43b,0x443,0x44b,0x2e0,0x2e8,0x450,0x458,0x45d,0x465,0x46d,0x475,0x474,0x47c,0x481,0x489,
+0x490,0x497,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x49f,0x4a0,0x4a8,0x4b0,0x4b4,0x4a0,0x4bc,0x4c4,
+0x4cc,0x4a0,0x4d4,0x4d9,0x4cc,0x4a0,0x4e1,0x4c4,0x4b4,0x4e5,0x4ed,0x4c4,0x4f2,0x2e0,0x4fa,0x2e0,
+0x2e0,0x476,0x502,0x4c4,0x2e0,0x4e5,0x509,0x4c4,0x2e0,0x2e0,0x4bc,0x4c4,0x2e0,0x2e0,0x50f,0x2e0,
+0x2e0,0x515,0x51c,0x2e0,0x2e0,0x520,0x528,0x2e0,0x52c,0x533,0x2e0,0x53a,0x542,0x549,0x551,0x2e0,
+0x2e0,0x556,0x55e,0x566,0x56e,0x576,0x57e,0x429,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x484,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x582,0x582,0x4c0,0x4c0,0x2e0,0x588,0x590,0x2e0,
+0x598,0x2e0,0x5a0,0x2e0,0x2e0,0x5a6,0x2e0,0x2e0,0x2e0,0x5ae,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x5b5,0x2e0,0x5bc,0x5c4,0x2e0,0x59f,0x2e0,0x2e0,0x5cc,0x5cf,0x5d7,0x5dd,0x5e5,0x5ed,0x2e0,0x2e0,
+0x2e0,0x5f2,0x2e0,0x5f8,0x2e0,0x2e0,0x600,0x608,0x610,0x615,0x618,0x620,0x628,0x62f,0x637,0x63e,
+0x307,0x646,0x307,0x64e,0x651,0x307,0x659,0x307,0x661,0x669,0x671,0x679,0x681,0x689,0x691,0x699,
+0x6a1,0x6a8,0x2e0,0x6b0,0x6b8,0x2e0,0x6be,0x6c6,0x6ce,0x6d6,0x6de,0x6e6,0x6ee,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x6f1,0x6f7,0x6fd,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x705,0x70a,0x70e,0x716,0x307,0x307,0x307,0x71e,0x726,0x72e,0x2e0,0x59d,0x2e0,0x2e0,0x2e0,0x736,
+0x2e0,0x59d,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x4b3,0x73e,0x2e0,0x2e0,0x745,0x2e0,0x2e0,0x74d,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x755,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x5f8,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x75b,0x2e0,0x307,0x763,0x76b,0x2e0,0x2e0,0x771,0x779,0x781,0x307,0x786,0x78e,0x2e0,0x2e0,0x2e0,
+0x796,0x4cb,0x2e0,0x2e0,0x2e0,0x2e0,0x79d,0x7a5,0x2e0,0x7ac,0x7b3,0x2e0,0x49f,0x7b8,0x7c0,0x2e0,
+0x2e0,0x7c6,0x7ce,0x7d2,0x2e0,0x7d7,0x7df,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x7e5,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,
+0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x7ed,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x7f5,0x7fd,0x801,0x2e0,0x2e0,0x2e0,0x2e0,0x2c3,0x2c9,0x809,0x811,0x7d2,0x476,0x2e0,0x2e0,0x819,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0xb84,0xb84,0xb9c,0xbdc,0xc1c,0xc58,0xc98,0xcd8,0xd10,0xd50,0xd90,0xdd0,0xe10,0xe50,0xe90,0xed0,
+0xf10,0xf40,0xf80,0xfc0,0xfdc,0x1010,0x104c,0x108c,0x10cc,0x110c,0xb80,0x1140,0x1174,0x11b4,0x11d0,0x1204,
+0x9e1,0xa11,0xa4d,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0xa82,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,0x188,
+0xac2,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x5a1,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x821,0x827,0x82b,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x833,0x837,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x5e5,0x83f,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x847,0x84f,0x855,
+0x2e0,0x2e0,0x2e0,0x2e0,0x85d,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x865,0x86d,0x872,0x878,0x880,0x888,0x890,0x869,0x898,0x8a0,0x8a8,0x8af,0x86a,0x865,
+0x86d,0x868,0x878,0x86b,0x866,0x8b7,0x869,0x8bf,0x8c7,0x8cf,0x8d6,0x8c2,0x8ca,0x8d2,0x8d9,0x8c5,
+0x8e1,0x2e0,0x4b4,0x779,0x779,0x779,0x2e0,0x2e0,0x2e0,0x2e0,0x779,0x779,0x779,0x779,0x779,0x779,
+0x779,0x8e9,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,0x2e0,
+0x2e0,0x2e0,0x2c0,0x2c0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0x40,0,0,0,0,
+0,0,0x40,0,0,0,0,0,0,0,0,0,0,0,0x40,0,
+0,0,0,0,0,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0xe,0x5e,0x7e,
+0x806,0x806,0x806,0x806,0x806,0x806,0x806,0xbe,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0,
+0,0,0x40,0,0x40,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xfd,0xf815,0x14d,
+0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0x18d,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x40,0,1,0,0,0x40,0,0x40,0,0,0,0,
+0x40,0x1cd,0,0x40,0x40,0,1,0,0,0,0,0,0x806,0x806,0x806,0x806,
+0x806,0x1fe,0x806,0x806,0x806,0x806,0x806,0x806,0x23e,0x25e,0x806,0x806,0x806,0x806,0x806,0x806,
+0x806,0x806,0x806,0,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x27d,0xf805,0xf805,0xf805,0xf805,
+0xf805,0x31d,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,
+0xf805,0xf805,0xf805,0,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0x1e45,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x35e,0xffc5,0x46,0xffc5,0x46,0xffc5,0x37e,0xffd5,0x39e,0x3ed,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,1,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,
+0xffc5,0x43d,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0xe1c6,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x4bd,0x30c5,0x3486,0x46,0xffc5,0x46,0xffc5,0x3386,0x46,
+0xffc5,0x3346,0x3346,0x46,0xffc5,1,0x13c6,0x3286,0x32c6,0x46,0xffc5,0x3346,0x33c6,0x1845,0x34c6,0x3446,
+0x46,0xffc5,0x28c5,1,0x34c6,0x3546,0x2085,0x3586,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x3686,0x46,
+0xffc5,0x3686,1,1,0x46,0xffc5,0x3686,0x46,0xffc5,0x3646,0x3646,0x46,0xffc5,0x46,0xffc5,0x36c6,
+0x46,0xffc5,1,0,0x46,0xffc5,1,0xe05,0,0,0,0,0x4ee,0x51f,0x55d,0x58e,
+0x5bf,0x5fd,0x62e,0x65f,0x69d,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,
+0xffc5,0x46,0xffc5,0x46,0xffc5,0xec45,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x6cd,0x74e,0x77f,0x7bd,0x46,0xffc5,0xe7c6,0xf206,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0xdf86,1,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,1,1,1,1,1,1,0x7ee,0x46,0xffc5,0xd746,0x80e,0x82d,
+0x84d,0x46,0xffc5,0xcf46,0x1146,0x11c6,0x46,0xffc5,0x46,0xffd5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x86d,0x88d,0x8ad,0xcb85,0xcc85,1,0xccc5,0xccc5,1,0xcd85,1,0xcd45,1,1,1,1,
+0xccc5,1,1,0xcc45,1,1,1,1,0xcbd5,0xcb45,1,0x8cd,1,1,1,0xcb45,
+1,0x8ed,0xcac5,1,1,0xca85,1,1,1,1,1,1,1,0x90d,1,1,
+0xc985,1,1,0xc985,1,1,1,1,0xc985,0xeec5,0xc9c5,0xc9c5,0xee45,1,1,1,
+1,1,0xc945,1,0,1,1,1,1,1,1,1,1,0x11,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+0x929,0x929,0x939,0x929,0x929,0x929,0x929,0x929,0x929,0x40,0x40,0x40,0x44,0x40,0x44,0x40,
+0x929,0x929,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x929,0x929,0x929,0x929,0x929,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x64,0x64,0x60,0x60,0x60,0x60,0x60,0x94c,0x64,0x60,0x64,0x60,0x64,0x60,0x60,0x60,
+0x60,0x60,0x60,0x64,0x60,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,
+0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,
+0x70,0x74,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x60,0x60,0x60,
+0x60,0x60,0x64,0x60,0x60,0x95d,0x60,0x70,0x70,0x70,0x60,0x60,0x60,0x70,0x70,0x40,
+0x60,0x60,0x60,0x70,0x70,0x70,0x70,0x60,0x70,0x70,0x70,0x60,0x70,0x70,0x70,0x70,
+0x70,0x70,0x70,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+0x46,0xffc5,0x46,0xffc5,0x40,0x40,0x46,0xffc5,0,0,0x929,0x2085,0x2085,0x2085,0,0,
+0,0,0,0,0x40,0x40,0x986,0x40,0x946,0x946,0x946,0,0x1006,0,0xfc6,0xfc6,
+0x9ad,0x806,0xa7e,0x806,0x806,0xabe,0x806,0x806,0xafe,0xb4e,0xb9e,0x806,0xbde,0x806,0x806,0x806,
+0xc1e,0xc5e,0,0xc9e,0x806,0x806,0xcde,0x806,0x806,0xd1e,0x806,0x806,0xf685,0xf6c5,0xf6c5,0xf6c5,
+0xd5d,0xf805,0xe2d,0xf805,0xf805,0xe6d,0xf805,0xf805,0xead,0xefd,0xf4d,0xf805,0xf8d,0xf805,0xf805,0xf805,
+0xfcd,0x100d,0x104d,0x107d,0xf805,0xf805,0x10bd,0xf805,0xf805,0x10fd,0xf805,0xf805,0xf005,0xf045,0xf045,0x206,
+0x113d,0x116d,2,2,2,0x11bd,0x11ed,0xfe05,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x121d,0x124d,0x1c5,0x11,0x127e,0x12cd,0,0x46,0xffc5,0xfe46,0x46,0xffc5,1,0xdf86,0xdf86,0xdf86,
+0x1406,0x1406,0x1406,0x1406,0x1406,0x1406,0x1406,0x1406,0x1406,0x1406,0x1406,0x1406,0x1406,0x1406,0x1406,0x1406,
+0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,
+0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,
+0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,
+0xec05,0xec05,0xec05,0xec05,0xec05,0xec05,0xec15,0xec05,0xec15,0xec05,0xec05,0xec05,0xec05,0xec05,0xec05,0xec05,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0,0x60,0x60,0x60,0x60,0x60,0x40,0x40,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x3c6,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0xfc45,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0,0,0,0,0,0,0,0,0,0,0,0xc06,0xc06,0xc06,
+0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,
+0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0,0,0x40,0,0,0,0,0,0,
+0,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,
+0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,
+0xf405,0xf405,0xf405,0x12fd,0,0,0,0,0,0,0,0,0,0x70,0x60,0x60,
+0x60,0x60,0x70,0x60,0x60,0x60,0x70,0x70,0x60,0x60,0x60,0x60,0x60,0x60,0x70,0x70,
+0x70,0x70,0x70,0x70,0x60,0x60,0x70,0x60,0x60,0x70,0x70,0x60,0x70,0x70,0x70,0x70,
+0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0,0x70,0,0x70,0x70,0,
+0x60,0x70,0,0x70,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x40,0,0,0,0,0,0,0,0,0,0,0,0x40,0x40,0x40,0x40,
+0,0,0,0,0,0,0,0,0,0,0,0,0x60,0x60,0x60,0x60,
+0x60,0x60,0x60,0x60,0x70,0x70,0x70,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x40,0,0,0,
+0,0,0,0,0,0,0,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x60,
+0x60,0x70,0x70,0x60,0x60,0x60,0x60,0x60,0x70,0x60,0x60,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x70,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x40,0x40,0x60,
+0x60,0x60,0x60,0x70,0x60,0x40,0x40,0x60,0x60,0,0x70,0x60,0x60,0x70,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0x40,0,0x70,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x60,0x70,0x60,0x60,0x70,0x60,0x60,0x70,0x70,0x70,0x60,0x70,
+0x70,0x60,0x70,0x60,0x60,0x60,0x70,0x60,0x70,0x60,0x70,0x60,0x70,0x60,0x60,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x60,
+0x60,0x60,0x60,0x60,0x60,0x60,0x70,0x60,0x40,0x40,0,0,0,0,0x40,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0x60,0x60,0x60,0x60,0x40,0x60,0x60,0x60,0x60,0x60,
+0x40,0x60,0x60,0x60,0x40,0x60,0x60,0x60,0x60,0x60,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x40,0x40,0x40,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x70,0,0,0,
+0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0,0,0,0,0x70,0,0,
+0,0x60,0x70,0x60,0x60,0x40,0,0,0,0,0,0,0,0,0,0,
+0,0,0x40,0x40,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0x40,0x40,0x40,0x40,0,0,0,0,0,0,0,0,0x70,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0x40,0x40,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0x40,0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0x40,0x40,0,0,0,0,0x40,0x40,0,0,0x40,0x40,0x70,0,0,
+0,0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x40,0x40,0,0,0,0x40,0,0,0,0,0,0,
+0,0,0,0,0,0x40,0x40,0x40,0x40,0x40,0,0x40,0x40,0,0,0,
+0,0x70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x70,0,0,0x40,0,0x40,0x40,0x40,0x40,0,0,0,0,0,0,0,
+0,0x70,0,0,0,0,0,0,0,0,0x40,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x40,0,0,0,0,0,0,0,
+0,0,0,0,0,0x70,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x40,0,0,0,0,0,0x40,0x40,
+0x40,0,0x40,0x40,0x40,0x70,0,0,0,0,0,0,0,0x70,0x70,0,
+0,0,0,0,0,0,0,0,0,0,0x40,0,0,0,0,0,
+0x40,0x70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0x70,0,0,0,0,0,0,0,0x40,0x40,
+0x40,0,0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0x40,0,0,0x40,0x40,0x40,0x40,0x70,0x70,0x70,0,
+0,0,0,0,0,0,0x40,0x40,0x70,0x70,0x70,0x70,0x40,0x40,0x40,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0x40,0,0,0x40,0x40,0x40,0x40,0x70,0x70,0,0x40,0x40,0,0,0,
+0,0,0,0,0,0,0x40,0,0x70,0x70,0x70,0x70,0x40,0x40,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x70,0x70,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0x70,0,0x70,0,0x70,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0x70,0x70,0x40,0x70,0x40,0x40,0x40,
+0x40,0x40,0x70,0x70,0x70,0x70,0x40,0,0x70,0x40,0x60,0x60,0x70,0,0x60,0x60,
+0,0,0,0,0,0,0,0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x40,0,0,0,0,0,0,0,0,0,0x70,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0x40,0x40,0x40,0x40,0,0x40,0x40,0x40,0x40,0x40,0x70,
+0,0x70,0x70,0,0,0x40,0x40,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x40,0x40,0,0,0,0,0x40,0x40,0x40,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0x40,0x40,0x40,0x40,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0x40,0,0,0x40,0x40,0,
+0,0,0,0,0,0x70,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0x40,0,0,0x137e,0x139e,0x13be,0x13de,0x13fe,0x141e,0x143e,0x145e,
+0x147e,0x149e,0x14be,0x14de,0x14fe,0x151e,0x153e,0x155e,0x157e,0x159e,0x15be,0x15de,0x15fe,0x161e,0x163e,0x165e,
+0x167e,0x169e,0x16be,0x16de,0x16fe,0x171e,0x173e,0x175e,0x177e,0x179e,0x17be,0x17de,0x17fe,0x181e,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0x40,0x40,0x70,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x40,0x40,0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0,0,
+0,0,0,0,0,0,0x40,0,0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x40,0x40,0x70,0x40,0,0,0,0x40,0,0,0,0,0,0x60,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0x40,0x40,0x40,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0x40,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0x70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x40,0x40,0x40,0,0,0,0,0x40,
+0x40,0,0,0,0,0,0,0,0,0,0x40,0,0,0,0,0,
+0,0x70,0x60,0x70,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0x60,0x70,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0x40,0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0,
+0x70,0,0x40,0,0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0,0,0,
+0,0,0,0x40,0x40,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0,0,0x70,
+0x40,0x40,0x40,0x40,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x70,0,0x40,0x40,0x40,0x40,0x40,0,0x40,0,0,0,0,0,0x40,0,
+0x30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x60,
+0x70,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0,0,0,0,0,0,0,0,
+0,0,0,0,0x40,0x40,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0x40,0x40,0x40,0x40,0,0,0x40,0x40,0x30,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0,0,0x40,0x70,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x40,0x40,0x40,0x40,0x40,0x40,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x60,0x60,0x60,0,0x70,0x70,0x70,0x70,0x70,0x70,0x60,0x60,0x70,0x70,0x70,0x70,
+0x60,0,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0,0,0,0,0x70,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,
+0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,
+0x929,0x929,0x11,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,0x929,0x183d,1,1,1,0x185d,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,0x11,1,1,1,1,0x929,0x929,0x929,0x929,0x929,
+0x939,0x929,0x929,0x929,0x939,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,
+0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x929,0x60,0x60,0x70,0x60,
+0x60,0x60,0x60,0x60,0x60,0x60,0x70,0x60,0x60,0x70,0x70,0x70,0x70,0x60,0x60,0x60,
+0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0x70,0x60,0x70,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffd5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x187e,0x18bd,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x18fd,0x197d,0x19fd,0x1a7d,0x1afd,0x1b7d,
+1,1,0x1bae,1,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffd5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x205,0x205,0x205,0x205,0x205,0x205,0x205,0x205,0xfe06,0xfe06,0xfe06,0xfe06,
+0xfe06,0xfe06,0xfe06,0xfe06,0x205,0x205,0x205,0x205,0x205,0x205,0,0,0xfe06,0xfe06,0xfe06,0xfe06,
+0xfe06,0xfe06,0,0,0x205,0x205,0x205,0x205,0x205,0x205,0x205,0x205,0xfe06,0xfe06,0xfe06,0xfe06,
+0xfe06,0xfe06,0xfe06,0xfe06,0x205,0x205,0x205,0x205,0x205,0x205,0x205,0x205,0xfe06,0xfe06,0xfe06,0xfe06,
+0xfe06,0xfe06,0xfe06,0xfe06,0x205,0x205,0x205,0x205,0x205,0x205,0,0,0xfe06,0xfe06,0xfe06,0xfe06,
+0xfe06,0xfe06,0,0,0x1bfd,0x205,0x1c7d,0x205,0x1d2d,0x205,0x1ddd,0x205,0,0xfe06,0,0xfe06,
+0,0xfe06,0,0xfe06,0x205,0x205,0x205,0x205,0x205,0x205,0x205,0x205,0xfe06,0xfe06,0xfe06,0xfe06,
+0xfe06,0xfe06,0xfe06,0xfe06,0x1285,0x1285,0x1585,0x1585,0x1585,0x1585,0x1905,0x1905,0x2005,0x2005,0x1c05,0x1c05,
+0x1f85,0x1f85,0,0,0x1e8d,0x1efd,0x1f6d,0x1fdd,0x204d,0x20bd,0x212d,0x219d,0x220f,0x227f,0x22ef,0x235f,
+0x23cf,0x243f,0x24af,0x251f,0x258d,0x25fd,0x266d,0x26dd,0x274d,0x27bd,0x282d,0x289d,0x290f,0x297f,0x29ef,0x2a5f,
+0x2acf,0x2b3f,0x2baf,0x2c1f,0x2c8d,0x2cfd,0x2d6d,0x2ddd,0x2e4d,0x2ebd,0x2f2d,0x2f9d,0x300f,0x307f,0x30ef,0x315f,
+0x31cf,0x323f,0x32af,0x331f,0x205,0x205,0x338d,0x340d,0x347d,0,0x34fd,0x357d,0xfe06,0xfe06,0xed86,0xed86,
+0x362f,0x40,0x369d,0x40,0x40,0x40,0x36ed,0x376d,0x37dd,0,0x385d,0x38dd,0xea86,0xea86,0xea86,0xea86,
+0x398f,0x40,0x40,0x40,0x205,0x205,0x39fd,0x3aad,0,0,0x3b7d,0x3bfd,0xfe06,0xfe06,0xe706,0xe706,
+0,0x40,0x40,0x40,0x205,0x205,0x3cad,0x3d5d,0x3e2d,0x1c5,0x3ead,0x3f2d,0xfe06,0xfe06,0xe406,0xe406,
+0xfe46,0x40,0x40,0x40,0,0,0x3fdd,0x405d,0x40cd,0,0x414d,0x41cd,0xe006,0xe006,0xe086,0xe086,
+0x427f,0x40,0x40,0,0,0,0,0,0,0,0,0,0,0,0,0x40,
+0x40,0x40,0x40,0x40,0,0,0,0,0,0,0,0,0x40,0x40,0,0,
+0,0,0,0,0x40,0,0,0x40,0,0,0x40,0x40,0x40,0x40,0x40,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x40,0x40,0x40,0x40,0x40,0,0,0,0,0,0x40,0x40,0x40,0x40,0x40,0x40,
+0,0x50,0,0,0,0,0,0,0,0,0,0,0,0,0,0x40,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x929,0x929,0x929,0x929,0x929,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x60,0x60,0x70,0x70,0x60,0x60,0x60,0x60,
+0x70,0x70,0x70,0x60,0x60,0x40,0x40,0x40,0x40,0x60,0x40,0x40,0x40,0x70,0x70,0x60,
+0x70,0x60,0x70,0x70,0x70,0x70,0x70,0x70,0x60,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,2,
+0,0,1,2,2,2,1,1,2,2,2,1,0,2,0,0,
+0,2,2,2,2,2,0,0,0,0,0,0,2,0,0x42ee,0,
+2,0,0x432e,0x436e,2,2,0,1,2,2,0x706,2,1,0,0,0,
+0,1,0,0,1,1,2,2,0,0,0,0,0,2,1,1,
+0x11,0x11,0,0,0,0,0xf905,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x406,0x406,0x406,0x406,0x406,0x406,0x406,0x406,
+0x406,0x406,0x406,0x406,0x406,0x406,0x406,0x406,0xfc05,0xfc05,0xfc05,0xfc05,0xfc05,0xfc05,0xfc05,0xfc05,
+0xfc05,0xfc05,0xfc05,0xfc05,0xfc05,0xfc05,0xfc05,0xfc05,0,0,0,0x46,0xffc5,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0x686,0x686,0x686,0x686,0x686,0x686,
+0x686,0x686,0x686,0x686,0x686,0x686,0x686,0x686,0x686,0x686,0x686,0x686,0xf985,0xf985,0xf985,0xf985,
+0xf985,0xf985,0xf985,0xf985,0xf985,0xf985,0xf985,0xf985,0xf985,0xf985,0xf985,0xf985,0xf985,0xf985,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,
+0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,
+0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0xc06,0,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,
+0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,
+0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0xf405,0,0x46,0xffc5,0x43ae,0x43ce,0x43ee,0x440d,0x442d,0x46,
+0xffc5,0x46,0xffc5,0x46,0xffc5,0x444e,0x446e,0x448e,0x44ae,1,0x46,0xffc5,1,0x46,0xffc5,1,
+1,1,1,1,0x11,0x929,0x44ce,0x44ee,0x46,0xffc5,0x46,0xffc5,1,0,0,0,
+0,0,0,0x46,0xffc5,0x46,0xffc5,0x60,0x60,0x60,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x450d,0x452d,0x454d,0x456d,0x458d,0x45ad,0x45cd,0x45ed,
+0x460d,0x462d,0x464d,0x466d,0x468d,0x46ad,0x46cd,0x46ed,0x470d,0x472d,0x474d,0x476d,0x478d,0x47ad,0x47cd,0x47ed,
+0x480d,0x482d,0x484d,0x486d,0x488d,0x48ad,0x48cd,0x48ed,0x490d,0x492d,0x494d,0x496d,0x498d,0x49ad,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0,0,0,0,0,0,0,0,
+0,0,0x70,0x70,0x70,0x70,0x70,0x70,0,0x40,0x40,0x40,0x40,0x40,0,0,
+0,0,0,0x40,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0x70,0x70,0x40,
+0x40,0x40,0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x40,0x40,0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0x40,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x40,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0,0x60,0x40,0x40,0x40,0,
+0,0,0,0,0,0,0,0,0x60,0x60,0,0x40,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x60,0x60,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x40,0x40,0x40,0x40,0x40,0x40,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,1,1,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x929,1,1,1,1,1,1,1,
+1,0x46,0xffc5,0x46,0xffc5,0x49ce,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,0x46,0xffc5,
+0x40,0x40,0x40,0x46,0xffc5,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0x40,0,0,0,0x70,0,
+0,0,0,0x40,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x70,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+0x60,0x60,0x60,0x60,0x60,0x60,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0x40,0x40,0x40,0x40,0x40,0x70,0x70,0x70,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0,0x30,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0x70,0,0,0x40,0x40,0x40,0x40,0,0,0x40,0,0,0,
+0x30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x40,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0x40,0x40,0x40,0x40,0x40,0x40,0,0,0x40,0x40,0,0,0x40,0x40,0,
+0,0,0,0,0,0,0,0,0,0,0,0x40,0,0,0,0,
+0,0,0,0,0x40,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x40,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x60,0,0x60,0x60,
+0x70,0,0,0x60,0x60,0,0,0,0,0,0x60,0x60,0,0x60,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0x40,0,0,0x40,0,0,0,
+0,0x70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x49ed,0x4a6d,0x4aed,0x4b6d,0x4c1d,0x4ccd,0x4d6d,0,0,0,0,0,
+0,0,0,0,0,0,0,0x4e0d,0x4e8d,0x4f0d,0x4f8d,0x500d,0,0,0,0,
+0,0,0x70,0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x40,0x40,0x40,0x40,0,0,0,0x40,0,0,0,0,0,0,0,0,
+0,0,0,0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0x40,0,0,0x40,0,0,0,0,0,0,
+0,0,0,0,0,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,
+0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0x806,0,
+0,0,0x40,0,0x40,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,
+0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0xf805,0,
+0,0,0,0,0,0,0,0x40,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0x40,0x40,0x40,
+0,0,0,0,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,
+0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,0xa06,
+0xa06,0xa06,0xa06,0xa06,0xf605,0xf605,0xf605,0xf605,0xf605,0xf605,0xf605,0xf605,0xf605,0xf605,0xf605,0xf605,
+0xf605,0xf605,0xf605,0xf605,0xf605,0xf605,0xf605,0xf605,0xf605,0xf605,0xf605,0xf605,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0x40,0x40,0x40,
+0,0x40,0x40,0,0,0,0,0,0x40,0x70,0x40,0x60,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x60,0x70,0x70,0,0,0,0,0x70,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x40,
+0x40,0x40,0x40,0,0,0x70,0x70,0,0,0x40,0,0,0,0,0,0,
+0,0x30,0x30,0x70,0x70,0x70,0,0,0,0x30,0x30,0x30,0x30,0x30,0x30,0x40,
+0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0,
+0,0x60,0x60,0x60,0x60,0x60,0x70,0x70,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x60,0x60,
+0x60,0x60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0x60,0x60,0x60,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,
+1,1,1,1,1,1,0x11,0x11,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,1,1,1,1,1,1,1,0,0x11,0x11,
+1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,1,1,1,1,1,1,1,1,0x11,0x11,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,2,0,2,2,
+0,0,2,0,0,2,2,0,0,2,2,2,2,0,2,2,
+2,2,2,2,2,2,1,1,1,1,0,1,0,1,0x11,0x11,
+1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+1,1,1,1,2,2,0,2,2,2,2,0,0,2,2,2,
+2,2,2,2,2,0,2,2,2,2,2,2,2,0,1,1,
+1,1,1,1,1,1,0x11,0x11,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,2,2,0,2,2,2,2,0,
+2,2,2,2,2,0,2,0,0,0,2,2,2,2,2,2,
+2,0,1,1,1,1,1,1,1,1,0x11,0x11,1,1,1,1,
+1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,
+1,1,0,0,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,0,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,0,1,1,1,1,1,1,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,0,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
+1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,1,1,1,0,1,1,1,1,1,1,2,1,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+0x40,0x40,0x40,0x40,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0
+};
+
+static const uint16_t ucase_props_exceptions[1288]={
+0xc041,0x69,2,0x130,0x131,0x4001,0x6a,0x41,0x6b,1,0x212a,0x41,0x73,1,0x17f,0x5044,
+0x49,2,0x130,0x131,0x44,0x4b,1,0x212a,0x44,0x53,1,0x17f,6,0x3bc,0x39c,0x41,
+0xe5,1,0x212b,0x4001,0xec,0x4001,0xed,0xc0,1,0x2220,0x73,0x73,0x53,0x53,0x53,0x73,
+0x1e9e,0x44,0xc5,1,0x212b,0x4001,0x129,0x4001,0x12f,0xc041,0x69,2,0x131,0x49,0x44,0x49,
+2,0x69,0x130,0x80,0x2220,0x2bc,0x6e,0x2bc,0x4e,0x2bc,0x4e,6,0x73,0x53,9,0x1c6,
+0x1c5,0xd,0x1c6,0x1c4,0x1c5,0xc,0x1c4,0x1c5,9,0x1c9,0x1c8,0xd,0x1c9,0x1c7,0x1c8,0xc,
+0x1c7,0x1c8,9,0x1cc,0x1cb,0xd,0x1cc,0x1ca,0x1cb,0xc,0x1ca,0x1cb,0x80,0x2220,0x6a,0x30c,
+0x4a,0x30c,0x4a,0x30c,9,0x1f3,0x1f2,0xd,0x1f3,0x1f1,0x1f2,0xc,0x1f1,0x1f2,1,0x2c65,
+1,0x2c66,4,0x2c7e,4,0x2c7f,4,0x2c6f,4,0x2c6d,4,0x2c70,4,0x2c62,4,0x2c6e,
+4,0x2c64,0x800,0x1800,0x6800,0x3846,0x3b9,0x399,1,0x1fbe,0xc0,1,0x3330,0x3b9,0x308,0x301,
+0x399,0x308,0x301,0x399,0x308,0x301,0x1fd3,0x41,0x3b2,1,0x3d0,0x41,0x3b5,1,0x3f5,0x41,
+0x3b8,2,0x3d1,0x3f4,0x41,0x3b9,2,0x345,0x1fbe,0x41,0x3ba,1,0x3f0,0x41,0x3bc,1,
+0xb5,0x41,0x3c0,1,0x3d6,0x41,0x3c1,1,0x3f1,0x4041,0x3c3,1,0x3c2,0x41,0x3c6,1,
+0x3d5,0x41,0x3c9,1,0x2126,0xc0,1,0x3330,0x3c5,0x308,0x301,0x3a5,0x308,0x301,0x3a5,0x308,
+0x301,0x1fe3,0x44,0x392,1,0x3d0,0x44,0x395,1,0x3f5,0x44,0x398,2,0x3d1,0x3f4,0x44,
+0x399,2,0x345,0x1fbe,0x44,0x39a,1,0x3f0,0x44,0x39c,1,0xb5,0x44,0x3a0,1,0x3d6,
+0x44,0x3a1,1,0x3f1,6,0x3c3,0x3a3,0x44,0x3a3,1,0x3c2,0x44,0x3a6,1,0x3d5,0x44,
+0x3a9,1,0x2126,6,0x3b2,0x392,0x46,0x3b8,0x398,1,0x3f4,6,0x3c6,0x3a6,6,0x3c0,
+0x3a0,6,0x3ba,0x39a,6,0x3c1,0x3a1,0x41,0x3b8,2,0x398,0x3d1,6,0x3b5,0x395,0x80,
+0x2220,0x565,0x582,0x535,0x552,0x535,0x582,1,0x2d00,1,0x2d01,1,0x2d02,1,0x2d03,1,
+0x2d04,1,0x2d05,1,0x2d06,1,0x2d07,1,0x2d08,1,0x2d09,1,0x2d0a,1,0x2d0b,1,
+0x2d0c,1,0x2d0d,1,0x2d0e,1,0x2d0f,1,0x2d10,1,0x2d11,1,0x2d12,1,0x2d13,1,
+0x2d14,1,0x2d15,1,0x2d16,1,0x2d17,1,0x2d18,1,0x2d19,1,0x2d1a,1,0x2d1b,1,
+0x2d1c,1,0x2d1d,1,0x2d1e,1,0x2d1f,1,0x2d20,1,0x2d21,1,0x2d22,1,0x2d23,1,
+0x2d24,1,0x2d25,4,0xa77d,4,0x2c63,0x41,0x1e61,1,0x1e9b,0x44,0x1e60,1,0x1e9b,0x80,
+0x2220,0x68,0x331,0x48,0x331,0x48,0x331,0x80,0x2220,0x74,0x308,0x54,0x308,0x54,0x308,0x80,
+0x2220,0x77,0x30a,0x57,0x30a,0x57,0x30a,0x80,0x2220,0x79,0x30a,0x59,0x30a,0x59,0x30a,0x80,
+0x2220,0x61,0x2be,0x41,0x2be,0x41,0x2be,6,0x1e61,0x1e60,0x81,0xdf,0x20,0x73,0x73,0x80,
+0x2220,0x3c5,0x313,0x3a5,0x313,0x3a5,0x313,0x80,0x3330,0x3c5,0x313,0x300,0x3a5,0x313,0x300,0x3a5,
+0x313,0x300,0x80,0x3330,0x3c5,0x313,0x301,0x3a5,0x313,0x301,0x3a5,0x313,0x301,0x80,0x3330,0x3c5,
+0x313,0x342,0x3a5,0x313,0x342,0x3a5,0x313,0x342,0x84,0x1f88,0x220,0x1f00,0x3b9,0x1f08,0x399,0x84,
+0x1f89,0x220,0x1f01,0x3b9,0x1f09,0x399,0x84,0x1f8a,0x220,0x1f02,0x3b9,0x1f0a,0x399,0x84,0x1f8b,0x220,
+0x1f03,0x3b9,0x1f0b,0x399,0x84,0x1f8c,0x220,0x1f04,0x3b9,0x1f0c,0x399,0x84,0x1f8d,0x220,0x1f05,0x3b9,
+0x1f0d,0x399,0x84,0x1f8e,0x220,0x1f06,0x3b9,0x1f0e,0x399,0x84,0x1f8f,0x220,0x1f07,0x3b9,0x1f0f,0x399,
+0x81,0x1f80,0x220,0x1f00,0x3b9,0x1f08,0x399,0x81,0x1f81,0x220,0x1f01,0x3b9,0x1f09,0x399,0x81,0x1f82,
+0x220,0x1f02,0x3b9,0x1f0a,0x399,0x81,0x1f83,0x220,0x1f03,0x3b9,0x1f0b,0x399,0x81,0x1f84,0x220,0x1f04,
+0x3b9,0x1f0c,0x399,0x81,0x1f85,0x220,0x1f05,0x3b9,0x1f0d,0x399,0x81,0x1f86,0x220,0x1f06,0x3b9,0x1f0e,
+0x399,0x81,0x1f87,0x220,0x1f07,0x3b9,0x1f0f,0x399,0x84,0x1f98,0x220,0x1f20,0x3b9,0x1f28,0x399,0x84,
+0x1f99,0x220,0x1f21,0x3b9,0x1f29,0x399,0x84,0x1f9a,0x220,0x1f22,0x3b9,0x1f2a,0x399,0x84,0x1f9b,0x220,
+0x1f23,0x3b9,0x1f2b,0x399,0x84,0x1f9c,0x220,0x1f24,0x3b9,0x1f2c,0x399,0x84,0x1f9d,0x220,0x1f25,0x3b9,
+0x1f2d,0x399,0x84,0x1f9e,0x220,0x1f26,0x3b9,0x1f2e,0x399,0x84,0x1f9f,0x220,0x1f27,0x3b9,0x1f2f,0x399,
+0x81,0x1f90,0x220,0x1f20,0x3b9,0x1f28,0x399,0x81,0x1f91,0x220,0x1f21,0x3b9,0x1f29,0x399,0x81,0x1f92,
+0x220,0x1f22,0x3b9,0x1f2a,0x399,0x81,0x1f93,0x220,0x1f23,0x3b9,0x1f2b,0x399,0x81,0x1f94,0x220,0x1f24,
+0x3b9,0x1f2c,0x399,0x81,0x1f95,0x220,0x1f25,0x3b9,0x1f2d,0x399,0x81,0x1f96,0x220,0x1f26,0x3b9,0x1f2e,
+0x399,0x81,0x1f97,0x220,0x1f27,0x3b9,0x1f2f,0x399,0x84,0x1fa8,0x220,0x1f60,0x3b9,0x1f68,0x399,0x84,
+0x1fa9,0x220,0x1f61,0x3b9,0x1f69,0x399,0x84,0x1faa,0x220,0x1f62,0x3b9,0x1f6a,0x399,0x84,0x1fab,0x220,
+0x1f63,0x3b9,0x1f6b,0x399,0x84,0x1fac,0x220,0x1f64,0x3b9,0x1f6c,0x399,0x84,0x1fad,0x220,0x1f65,0x3b9,
+0x1f6d,0x399,0x84,0x1fae,0x220,0x1f66,0x3b9,0x1f6e,0x399,0x84,0x1faf,0x220,0x1f67,0x3b9,0x1f6f,0x399,
+0x81,0x1fa0,0x220,0x1f60,0x3b9,0x1f68,0x399,0x81,0x1fa1,0x220,0x1f61,0x3b9,0x1f69,0x399,0x81,0x1fa2,
+0x220,0x1f62,0x3b9,0x1f6a,0x399,0x81,0x1fa3,0x220,0x1f63,0x3b9,0x1f6b,0x399,0x81,0x1fa4,0x220,0x1f64,
+0x3b9,0x1f6c,0x399,0x81,0x1fa5,0x220,0x1f65,0x3b9,0x1f6d,0x399,0x81,0x1fa6,0x220,0x1f66,0x3b9,0x1f6e,
+0x399,0x81,0x1fa7,0x220,0x1f67,0x3b9,0x1f6f,0x399,0x80,0x2220,0x1f70,0x3b9,0x1fba,0x399,0x1fba,0x345,
+0x84,0x1fbc,0x220,0x3b1,0x3b9,0x391,0x399,0x80,0x2220,0x3ac,0x3b9,0x386,0x399,0x386,0x345,0x80,
+0x2220,0x3b1,0x342,0x391,0x342,0x391,0x342,0x80,0x3330,0x3b1,0x342,0x3b9,0x391,0x342,0x399,0x391,
+0x342,0x345,0x81,0x1fb3,0x220,0x3b1,0x3b9,0x391,0x399,0x46,0x3b9,0x399,1,0x345,0x80,0x2220,
+0x1f74,0x3b9,0x1fca,0x399,0x1fca,0x345,0x84,0x1fcc,0x220,0x3b7,0x3b9,0x397,0x399,0x80,0x2220,0x3ae,
+0x3b9,0x389,0x399,0x389,0x345,0x80,0x2220,0x3b7,0x342,0x397,0x342,0x397,0x342,0x80,0x3330,0x3b7,
+0x342,0x3b9,0x397,0x342,0x399,0x397,0x342,0x345,0x81,0x1fc3,0x220,0x3b7,0x3b9,0x397,0x399,0x80,
+0x3330,0x3b9,0x308,0x300,0x399,0x308,0x300,0x399,0x308,0x300,0xc0,1,0x3330,0x3b9,0x308,0x301,
+0x399,0x308,0x301,0x399,0x308,0x301,0x390,0x80,0x2220,0x3b9,0x342,0x399,0x342,0x399,0x342,0x80,
+0x3330,0x3b9,0x308,0x342,0x399,0x308,0x342,0x399,0x308,0x342,0x80,0x3330,0x3c5,0x308,0x300,0x3a5,
+0x308,0x300,0x3a5,0x308,0x300,0xc0,1,0x3330,0x3c5,0x308,0x301,0x3a5,0x308,0x301,0x3a5,0x308,
+0x301,0x3b0,0x80,0x2220,0x3c1,0x313,0x3a1,0x313,0x3a1,0x313,0x80,0x2220,0x3c5,0x342,0x3a5,0x342,
+0x3a5,0x342,0x80,0x3330,0x3c5,0x308,0x342,0x3a5,0x308,0x342,0x3a5,0x308,0x342,0x80,0x2220,0x1f7c,
+0x3b9,0x1ffa,0x399,0x1ffa,0x345,0x84,0x1ffc,0x220,0x3c9,0x3b9,0x3a9,0x399,0x80,0x2220,0x3ce,0x3b9,
+0x38f,0x399,0x38f,0x345,0x80,0x2220,0x3c9,0x342,0x3a9,0x342,0x3a9,0x342,0x80,0x3330,0x3c9,0x342,
+0x3b9,0x3a9,0x342,0x399,0x3a9,0x342,0x345,0x81,0x1ff3,0x220,0x3c9,0x3b9,0x3a9,0x399,0x41,0x3c9,
+1,0x3a9,0x41,0x6b,1,0x4b,0x41,0xe5,1,0xc5,1,0x26b,1,0x1d7d,1,0x27d,
+4,0x23a,4,0x23e,1,0x251,1,0x271,1,0x250,1,0x252,1,0x23f,1,0x240,
+4,0x10a0,4,0x10a1,4,0x10a2,4,0x10a3,4,0x10a4,4,0x10a5,4,0x10a6,4,0x10a7,
+4,0x10a8,4,0x10a9,4,0x10aa,4,0x10ab,4,0x10ac,4,0x10ad,4,0x10ae,4,0x10af,
+4,0x10b0,4,0x10b1,4,0x10b2,4,0x10b3,4,0x10b4,4,0x10b5,4,0x10b6,4,0x10b7,
+4,0x10b8,4,0x10b9,4,0x10ba,4,0x10bb,4,0x10bc,4,0x10bd,4,0x10be,4,0x10bf,
+4,0x10c0,4,0x10c1,4,0x10c2,4,0x10c3,4,0x10c4,4,0x10c5,1,0x1d79,0x80,0x2220,
+0x66,0x66,0x46,0x46,0x46,0x66,0x80,0x2220,0x66,0x69,0x46,0x49,0x46,0x69,0x80,0x2220,
+0x66,0x6c,0x46,0x4c,0x46,0x6c,0x80,0x3330,0x66,0x66,0x69,0x46,0x46,0x49,0x46,0x66,
+0x69,0x80,0x3330,0x66,0x66,0x6c,0x46,0x46,0x4c,0x46,0x66,0x6c,0xc0,1,0x2220,0x73,
+0x74,0x53,0x54,0x53,0x74,0xfb06,0xc0,1,0x2220,0x73,0x74,0x53,0x54,0x53,0x74,0xfb05,
+0x80,0x2220,0x574,0x576,0x544,0x546,0x544,0x576,0x80,0x2220,0x574,0x565,0x544,0x535,0x544,0x565,
+0x80,0x2220,0x574,0x56b,0x544,0x53b,0x544,0x56b,0x80,0x2220,0x57e,0x576,0x54e,0x546,0x54e,0x576,
+0x80,0x2220,0x574,0x56d,0x544,0x53d,0x544,0x56d
+};
+
+static const uint16_t ucase_props_unfold[370]={
+0x49,5,3,0,0,0x61,0x2be,0,0x1e9a,0,0x66,0x66,0,0xfb00,0,0x66,
+0x66,0x69,0xfb03,0,0x66,0x66,0x6c,0xfb04,0,0x66,0x69,0,0xfb01,0,0x66,0x6c,
+0,0xfb02,0,0x68,0x331,0,0x1e96,0,0x69,0x307,0,0x130,0,0x6a,0x30c,0,
+0x1f0,0,0x73,0x73,0,0xdf,0x1e9e,0x73,0x74,0,0xfb05,0xfb06,0x74,0x308,0,0x1e97,
+0,0x77,0x30a,0,0x1e98,0,0x79,0x30a,0,0x1e99,0,0x2bc,0x6e,0,0x149,0,
+0x3ac,0x3b9,0,0x1fb4,0,0x3ae,0x3b9,0,0x1fc4,0,0x3b1,0x342,0,0x1fb6,0,0x3b1,
+0x342,0x3b9,0x1fb7,0,0x3b1,0x3b9,0,0x1fb3,0x1fbc,0x3b7,0x342,0,0x1fc6,0,0x3b7,0x342,
+0x3b9,0x1fc7,0,0x3b7,0x3b9,0,0x1fc3,0x1fcc,0x3b9,0x308,0x300,0x1fd2,0,0x3b9,0x308,0x301,
+0x390,0x1fd3,0x3b9,0x308,0x342,0x1fd7,0,0x3b9,0x342,0,0x1fd6,0,0x3c1,0x313,0,0x1fe4,
+0,0x3c5,0x308,0x300,0x1fe2,0,0x3c5,0x308,0x301,0x3b0,0x1fe3,0x3c5,0x308,0x342,0x1fe7,0,
+0x3c5,0x313,0,0x1f50,0,0x3c5,0x313,0x300,0x1f52,0,0x3c5,0x313,0x301,0x1f54,0,0x3c5,
+0x313,0x342,0x1f56,0,0x3c5,0x342,0,0x1fe6,0,0x3c9,0x342,0,0x1ff6,0,0x3c9,0x342,
+0x3b9,0x1ff7,0,0x3c9,0x3b9,0,0x1ff3,0x1ffc,0x3ce,0x3b9,0,0x1ff4,0,0x565,0x582,0,
+0x587,0,0x574,0x565,0,0xfb14,0,0x574,0x56b,0,0xfb15,0,0x574,0x56d,0,0xfb17,
+0,0x574,0x576,0,0xfb13,0,0x57e,0x576,0,0xfb16,0,0x1f00,0x3b9,0,0x1f80,0x1f88,
+0x1f01,0x3b9,0,0x1f81,0x1f89,0x1f02,0x3b9,0,0x1f82,0x1f8a,0x1f03,0x3b9,0,0x1f83,0x1f8b,0x1f04,
+0x3b9,0,0x1f84,0x1f8c,0x1f05,0x3b9,0,0x1f85,0x1f8d,0x1f06,0x3b9,0,0x1f86,0x1f8e,0x1f07,0x3b9,
+0,0x1f87,0x1f8f,0x1f20,0x3b9,0,0x1f90,0x1f98,0x1f21,0x3b9,0,0x1f91,0x1f99,0x1f22,0x3b9,0,
+0x1f92,0x1f9a,0x1f23,0x3b9,0,0x1f93,0x1f9b,0x1f24,0x3b9,0,0x1f94,0x1f9c,0x1f25,0x3b9,0,0x1f95,
+0x1f9d,0x1f26,0x3b9,0,0x1f96,0x1f9e,0x1f27,0x3b9,0,0x1f97,0x1f9f,0x1f60,0x3b9,0,0x1fa0,0x1fa8,
+0x1f61,0x3b9,0,0x1fa1,0x1fa9,0x1f62,0x3b9,0,0x1fa2,0x1faa,0x1f63,0x3b9,0,0x1fa3,0x1fab,0x1f64,
+0x3b9,0,0x1fa4,0x1fac,0x1f65,0x3b9,0,0x1fa5,0x1fad,0x1f66,0x3b9,0,0x1fa6,0x1fae,0x1f67,0x3b9,
+0,0x1fa7,0x1faf,0x1f70,0x3b9,0,0x1fb2,0,0x1f74,0x3b9,0,0x1fc2,0,0x1f7c,0x3b9,0,
+0x1ff2,0
+};
+
+static const UCaseProps ucase_props_singleton={
+  NULL,
+  ucase_props_indexes,
+  ucase_props_exceptions,
+  ucase_props_unfold,
+  {
+    ucase_props_trieIndex,
+    ucase_props_trieIndex+2820,
+    NULL,
+    2820,
+    6340,
+    0x188,
+    0xb80,
+    0x0,
+    0x0,
+    0xe0800,
+    0x23c4,
+    NULL, 0, FALSE, FALSE, 0, NULL
+  },
+  { 2,1,0,0 }
+};
diff --git a/icu/source/common/ucasemap.c b/icu/source/common/ucasemap.c
new file mode 100644
index 0000000..67f5787
--- /dev/null
+++ b/icu/source/common/ucasemap.c
@@ -0,0 +1,574 @@
+/*
+*******************************************************************************
+*
+*   Copyright (C) 2005-2009, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+*******************************************************************************
+*   file name:  ucasemap.c
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2005may06
+*   created by: Markus W. Scherer
+*
+*   Case mapping service object and functions using it.
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/uloc.h"
+#include "unicode/ustring.h"
+#include "unicode/ucasemap.h"
+#if !UCONFIG_NO_BREAK_ITERATION
+#include "unicode/ubrk.h"
+#include "unicode/utext.h"
+#endif
+#include "cmemory.h"
+#include "cstring.h"
+#include "ucase.h"
+#include "ustr_imp.h"
+
+/* UCaseMap service object -------------------------------------------------- */
+
+U_CAPI UCaseMap * U_EXPORT2
+ucasemap_open(const char *locale, uint32_t options, UErrorCode *pErrorCode) {
+    UCaseMap *csm;
+
+    if(U_FAILURE(*pErrorCode)) {
+        return NULL;
+    }
+
+    csm=(UCaseMap *)uprv_malloc(sizeof(UCaseMap));
+    if(csm==NULL) {
+        return NULL;
+    }
+    uprv_memset(csm, 0, sizeof(UCaseMap));
+
+    csm->csp=ucase_getSingleton(pErrorCode);
+    ucasemap_setLocale(csm, locale, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        uprv_free(csm);
+        return NULL;
+    }
+
+    csm->options=options;
+    return csm;
+}
+
+U_CAPI void U_EXPORT2
+ucasemap_close(UCaseMap *csm) {
+    if(csm!=NULL) {
+#if !UCONFIG_NO_BREAK_ITERATION
+        ubrk_close(csm->iter);
+#endif
+        uprv_free(csm);
+    }
+}
+
+U_CAPI const char * U_EXPORT2
+ucasemap_getLocale(const UCaseMap *csm) {
+    return csm->locale;
+}
+
+U_CAPI uint32_t U_EXPORT2
+ucasemap_getOptions(const UCaseMap *csm) {
+    return csm->options;
+}
+
+U_CAPI void U_EXPORT2
+ucasemap_setLocale(UCaseMap *csm, const char *locale, UErrorCode *pErrorCode) {
+    int32_t length;
+
+    if(U_FAILURE(*pErrorCode)) {
+        return;
+    }
+
+    length=uloc_getName(locale, csm->locale, (int32_t)sizeof(csm->locale), pErrorCode);
+    if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR || length==sizeof(csm->locale)) {
+        *pErrorCode=U_ZERO_ERROR;
+        /* we only really need the language code for case mappings */
+        length=uloc_getLanguage(locale, csm->locale, (int32_t)sizeof(csm->locale), pErrorCode);
+    }
+    if(length==sizeof(csm->locale)) {
+        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
+    }
+    csm->locCache=0;
+    if(U_SUCCESS(*pErrorCode)) {
+        ucase_getCaseLocale(csm->locale, &csm->locCache);
+    } else {
+        csm->locale[0]=0;
+    }
+}
+
+U_CAPI void U_EXPORT2
+ucasemap_setOptions(UCaseMap *csm, uint32_t options, UErrorCode *pErrorCode) {
+    csm->options=options;
+}
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+U_CAPI const UBreakIterator * U_EXPORT2
+ucasemap_getBreakIterator(const UCaseMap *csm) {
+    return csm->iter;
+}
+
+U_CAPI void U_EXPORT2
+ucasemap_setBreakIterator(UCaseMap *csm, UBreakIterator *iterToAdopt, UErrorCode *pErrorCode) {
+    ubrk_close(csm->iter);
+    csm->iter=iterToAdopt;
+}
+
+#endif
+
+/* UTF-8 string case mappings ----------------------------------------------- */
+
+/* TODO(markus): Move to a new, separate utf8case.c file. */
+
+/* append a full case mapping result, see UCASE_MAX_STRING_LENGTH */
+static U_INLINE int32_t
+appendResult(uint8_t *dest, int32_t destIndex, int32_t destCapacity,
+             int32_t result, const UChar *s) {
+    UChar32 c;
+    int32_t length, destLength;
+    UErrorCode errorCode;
+
+    /* decode the result */
+    if(result<0) {
+        /* (not) original code point */
+        c=~result;
+        length=-1;
+    } else if(result<=UCASE_MAX_STRING_LENGTH) {
+        c=U_SENTINEL;
+        length=result;
+    } else {
+        c=result;
+        length=-1;
+    }
+
+    if(destIndex<destCapacity) {
+        /* append the result */
+        if(length<0) {
+            /* code point */
+            UBool isError=FALSE;
+            U8_APPEND(dest, destIndex, destCapacity, c, isError);
+            if(isError) {
+                /* overflow, nothing written */
+                destIndex+=U8_LENGTH(c);
+            }
+        } else {
+            /* string */
+            errorCode=U_ZERO_ERROR;
+            u_strToUTF8(
+                (char *)(dest+destIndex), destCapacity-destIndex, &destLength,
+                s, length,
+                &errorCode);
+            destIndex+=destLength;
+            /* we might have an overflow, but we know the actual length */
+        }
+    } else {
+        /* preflight */
+        if(length<0) {
+            destIndex+=U8_LENGTH(c);
+        } else {
+            errorCode=U_ZERO_ERROR;
+            u_strToUTF8(
+                NULL, 0, &destLength,
+                s, length,
+                &errorCode);
+            destIndex+=destLength;
+        }
+    }
+    return destIndex;
+}
+
+static UChar32 U_CALLCONV
+utf8_caseContextIterator(void *context, int8_t dir) {
+    UCaseContext *csc=(UCaseContext *)context;
+    UChar32 c;
+
+    if(dir<0) {
+        /* reset for backward iteration */
+        csc->index=csc->cpStart;
+        csc->dir=dir;
+    } else if(dir>0) {
+        /* reset for forward iteration */
+        csc->index=csc->cpLimit;
+        csc->dir=dir;
+    } else {
+        /* continue current iteration direction */
+        dir=csc->dir;
+    }
+
+    if(dir<0) {
+        if(csc->start<csc->index) {
+            U8_PREV((const uint8_t *)csc->p, csc->start, csc->index, c);
+            return c;
+        }
+    } else {
+        if(csc->index<csc->limit) {
+            U8_NEXT((const uint8_t *)csc->p, csc->index, csc->limit, c);
+            return c;
+        }
+    }
+    return U_SENTINEL;
+}
+
+/*
+ * Case-maps [srcStart..srcLimit[ but takes
+ * context [0..srcLength[ into account.
+ */
+static int32_t
+_caseMap(const UCaseMap *csm, UCaseMapFull *map,
+         uint8_t *dest, int32_t destCapacity,
+         const uint8_t *src, UCaseContext *csc,
+         int32_t srcStart, int32_t srcLimit,
+         UErrorCode *pErrorCode) {
+    const UChar *s;
+    UChar32 c, c2 = 0;
+    int32_t srcIndex, destIndex;
+    int32_t locCache;
+
+    locCache=csm->locCache;
+
+    /* case mapping loop */
+    srcIndex=srcStart;
+    destIndex=0;
+    while(srcIndex<srcLimit) {
+        csc->cpStart=srcIndex;
+        U8_NEXT(src, srcIndex, srcLimit, c);
+        csc->cpLimit=srcIndex;
+        if(c<0) {
+            int32_t i=csc->cpStart;
+            while(destIndex<destCapacity && i<srcIndex) {
+                dest[destIndex++]=src[i++];
+            }
+            continue;
+        }
+        c=map(csm->csp, c, utf8_caseContextIterator, csc, &s, csm->locale, &locCache);
+        if((destIndex<destCapacity) && (c<0 ? (c2=~c)<=0x7f : UCASE_MAX_STRING_LENGTH<c && (c2=c)<=0x7f)) {
+            /* fast path version of appendResult() for ASCII results */
+            dest[destIndex++]=(uint8_t)c2;
+        } else {
+            destIndex=appendResult(dest, destIndex, destCapacity, c, s);
+        }
+    }
+
+    if(destIndex>destCapacity) {
+        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
+    }
+    return destIndex;
+}
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+/*
+ * Internal titlecasing function.
+ */
+static int32_t
+_toTitle(UCaseMap *csm,
+         uint8_t *dest, int32_t destCapacity,
+         const uint8_t *src, UCaseContext *csc,
+         int32_t srcLength,
+         UErrorCode *pErrorCode) {
+    UText utext=UTEXT_INITIALIZER;
+    const UChar *s;
+    UChar32 c;
+    int32_t prev, titleStart, titleLimit, idx, destIndex, length;
+    UBool isFirstIndex;
+
+    utext_openUTF8(&utext, (const char *)src, srcLength, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+    if(csm->iter==NULL) {
+        csm->iter=ubrk_open(UBRK_WORD, csm->locale,
+                            NULL, 0,
+                            pErrorCode);
+    }
+    ubrk_setUText(csm->iter, &utext, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        utext_close(&utext);
+        return 0;
+    }
+
+    /* set up local variables */
+    destIndex=0;
+    prev=0;
+    isFirstIndex=TRUE;
+
+    /* titlecasing loop */
+    while(prev<srcLength) {
+        /* find next index where to titlecase */
+        if(isFirstIndex) {
+            isFirstIndex=FALSE;
+            idx=ubrk_first(csm->iter);
+        } else {
+            idx=ubrk_next(csm->iter);
+        }
+        if(idx==UBRK_DONE || idx>srcLength) {
+            idx=srcLength;
+        }
+
+        /*
+         * Unicode 4 & 5 section 3.13 Default Case Operations:
+         *
+         * R3  toTitlecase(X): Find the word boundaries based on Unicode Standard Annex
+         * #29, "Text Boundaries." Between each pair of word boundaries, find the first
+         * cased character F. If F exists, map F to default_title(F); then map each
+         * subsequent character C to default_lower(C).
+         *
+         * In this implementation, segment [prev..index[ into 3 parts:
+         * a) uncased characters (copy as-is) [prev..titleStart[
+         * b) first case letter (titlecase)         [titleStart..titleLimit[
+         * c) subsequent characters (lowercase)                 [titleLimit..index[
+         */
+        if(prev<idx) {
+            /* find and copy uncased characters [prev..titleStart[ */
+            titleStart=titleLimit=prev;
+            U8_NEXT(src, titleLimit, idx, c);
+            if((csm->options&U_TITLECASE_NO_BREAK_ADJUSTMENT)==0 && UCASE_NONE==ucase_getType(csm->csp, c)) {
+                /* Adjust the titlecasing index (titleStart) to the next cased character. */
+                for(;;) {
+                    titleStart=titleLimit;
+                    if(titleLimit==idx) {
+                        /*
+                         * only uncased characters in [prev..index[
+                         * stop with titleStart==titleLimit==index
+                         */
+                        break;
+                    }
+                    U8_NEXT(src, titleLimit, idx, c);
+                    if(UCASE_NONE!=ucase_getType(csm->csp, c)) {
+                        break; /* cased letter at [titleStart..titleLimit[ */
+                    }
+                }
+                length=titleStart-prev;
+                if(length>0) {
+                    if((destIndex+length)<=destCapacity) {
+                        uprv_memcpy(dest+destIndex, src+prev, length);
+                    }
+                    destIndex+=length;
+                }
+            }
+
+            if(titleStart<titleLimit) {
+                /* titlecase c which is from [titleStart..titleLimit[ */
+                csc->cpStart=titleStart;
+                csc->cpLimit=titleLimit;
+                c=ucase_toFullTitle(csm->csp, c, utf8_caseContextIterator, csc, &s, csm->locale, &csm->locCache);
+                destIndex=appendResult(dest, destIndex, destCapacity, c, s);
+
+                
+                /* Special case Dutch IJ titlecasing */
+                if ( titleStart+1 < idx && 
+                     ucase_getCaseLocale(csm->locale,&csm->locCache) == UCASE_LOC_DUTCH &&
+                     ( src[titleStart] == 0x0049 || src[titleStart] == 0x0069 ) &&
+                     ( src[titleStart+1] == 0x004A || src[titleStart+1] == 0x006A )) { 
+                            c=0x004A;
+                            destIndex=appendResult(dest, destIndex, destCapacity, c, s);
+                            titleLimit++;
+                }
+                /* lowercase [titleLimit..index[ */
+                if(titleLimit<idx) {
+                    if((csm->options&U_TITLECASE_NO_LOWERCASE)==0) {
+                        /* Normal operation: Lowercase the rest of the word. */
+                        destIndex+=
+                            _caseMap(
+                                csm, ucase_toFullLower,
+                                dest+destIndex, destCapacity-destIndex,
+                                src, csc,
+                                titleLimit, idx,
+                                pErrorCode);
+                    } else {
+                        /* Optionally just copy the rest of the word unchanged. */
+                        length=idx-titleLimit;
+                        if((destIndex+length)<=destCapacity) {
+                            uprv_memcpy(dest+destIndex, src+titleLimit, length);
+                        }
+                        destIndex+=length;
+                    }
+                }
+            }
+        }
+
+        prev=idx;
+    }
+
+    if(destIndex>destCapacity) {
+        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
+    }
+    utext_close(&utext);
+    return destIndex;
+}
+
+#endif
+
+static int32_t
+utf8_foldCase(const UCaseProps *csp,
+              uint8_t *dest, int32_t destCapacity,
+              const uint8_t *src, int32_t srcLength,
+              uint32_t options,
+              UErrorCode *pErrorCode) {
+    int32_t srcIndex, destIndex;
+
+    const UChar *s;
+    UChar32 c, c2;
+    int32_t start;
+
+    /* case mapping loop */
+    srcIndex=destIndex=0;
+    while(srcIndex<srcLength) {
+        start=srcIndex;
+        U8_NEXT(src, srcIndex, srcLength, c);
+        if(c<0) {
+            while(destIndex<destCapacity && start<srcIndex) {
+                dest[destIndex++]=src[start++];
+            }
+            continue;
+        }
+        c=ucase_toFullFolding(csp, c, &s, options);
+        if((destIndex<destCapacity) && (c<0 ? (c2=~c)<=0x7f : UCASE_MAX_STRING_LENGTH<c && (c2=c)<=0x7f)) {
+            /* fast path version of appendResult() for ASCII results */
+            dest[destIndex++]=(uint8_t)c2;
+        } else {
+            destIndex=appendResult(dest, destIndex, destCapacity, c, s);
+        }
+    }
+
+    if(destIndex>destCapacity) {
+        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
+    }
+    return destIndex;
+}
+
+/*
+ * Implement argument checking and buffer handling
+ * for string case mapping as a common function.
+ */
+
+/* common internal function for public API functions */
+
+static int32_t
+caseMap(const UCaseMap *csm,
+        uint8_t *dest, int32_t destCapacity,
+        const uint8_t *src, int32_t srcLength,
+        int32_t toWhichCase,
+        UErrorCode *pErrorCode) {
+    int32_t destLength;
+
+    /* check argument values */
+    if(U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+    if( destCapacity<0 ||
+        (dest==NULL && destCapacity>0) ||
+        src==NULL ||
+        srcLength<-1
+    ) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    /* get the string length */
+    if(srcLength==-1) {
+        srcLength=(int32_t)uprv_strlen((const char *)src);
+    }
+
+    /* check for overlapping source and destination */
+    if( dest!=NULL &&
+        ((src>=dest && src<(dest+destCapacity)) ||
+         (dest>=src && dest<(src+srcLength)))
+    ) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    destLength=0;
+
+    if(toWhichCase==FOLD_CASE) {
+        destLength=utf8_foldCase(csm->csp, dest, destCapacity, src, srcLength,
+                                 csm->options, pErrorCode);
+    } else {
+        UCaseContext csc={ NULL };
+
+        csc.p=(void *)src;
+        csc.limit=srcLength;
+
+        if(toWhichCase==TO_LOWER) {
+            destLength=_caseMap(csm, ucase_toFullLower,
+                                dest, destCapacity,
+                                src, &csc,
+                                0, srcLength,
+                                pErrorCode);
+        } else if(toWhichCase==TO_UPPER) {
+            destLength=_caseMap(csm, ucase_toFullUpper,
+                                dest, destCapacity,
+                                src, &csc,
+                                0, srcLength,
+                                pErrorCode);
+        } else /* if(toWhichCase==TO_TITLE) */ {
+#if UCONFIG_NO_BREAK_ITERATION
+            *pErrorCode=U_UNSUPPORTED_ERROR;
+#else
+            /* UCaseMap is actually non-const in toTitle() APIs. */
+            UCaseMap *tmp = (UCaseMap *)csm;
+            destLength=_toTitle(tmp, dest, destCapacity,
+                                src, &csc, srcLength,
+                                pErrorCode);
+#endif
+        }
+    }
+
+    return u_terminateChars((char *)dest, destCapacity, destLength, pErrorCode);
+}
+
+/* public API functions */
+
+U_CAPI int32_t U_EXPORT2
+ucasemap_utf8ToLower(const UCaseMap *csm,
+                     char *dest, int32_t destCapacity,
+                     const char *src, int32_t srcLength,
+                     UErrorCode *pErrorCode) {
+    return caseMap(csm,
+                   (uint8_t *)dest, destCapacity,
+                   (const uint8_t *)src, srcLength,
+                   TO_LOWER, pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+ucasemap_utf8ToUpper(const UCaseMap *csm,
+                     char *dest, int32_t destCapacity,
+                     const char *src, int32_t srcLength,
+                     UErrorCode *pErrorCode) {
+    return caseMap(csm,
+                   (uint8_t *)dest, destCapacity,
+                   (const uint8_t *)src, srcLength,
+                   TO_UPPER, pErrorCode);
+}
+
+#if !UCONFIG_NO_BREAK_ITERATION
+
+U_CAPI int32_t U_EXPORT2
+ucasemap_utf8ToTitle(UCaseMap *csm,
+                     char *dest, int32_t destCapacity,
+                     const char *src, int32_t srcLength,
+                     UErrorCode *pErrorCode) {
+    return caseMap(csm,
+                   (uint8_t *)dest, destCapacity,
+                   (const uint8_t *)src, srcLength,
+                   TO_TITLE, pErrorCode);
+}
+
+#endif
+
+U_CAPI int32_t U_EXPORT2
+ucasemap_utf8FoldCase(const UCaseMap *csm,
+                      char *dest, int32_t destCapacity,
+                      const char *src, int32_t srcLength,
+                      UErrorCode *pErrorCode) {
+    return caseMap(csm,
+                   (uint8_t *)dest, destCapacity,
+                   (const uint8_t *)src, srcLength,
+                   FOLD_CASE, pErrorCode);
+}
diff --git a/icu/source/common/ucat.c b/icu/source/common/ucat.c
new file mode 100644
index 0000000..5f6feb9
--- /dev/null
+++ b/icu/source/common/ucat.c
@@ -0,0 +1,76 @@
+/*
+**********************************************************************
+* Copyright (c) 2003, International Business Machines
+* Corporation and others.  All Rights Reserved.
+**********************************************************************
+* Author: Alan Liu
+* Created: March 19 2003
+* Since: ICU 2.6
+**********************************************************************
+*/
+#include "unicode/ucat.h"
+#include "unicode/ustring.h"
+#include "cstring.h"
+#include "uassert.h"
+
+/* Separator between set_num and msg_num */
+static const char SEPARATOR = '%';
+
+/* Maximum length of a set_num/msg_num key, incl. terminating zero.
+ * Longest possible key is "-2147483648%-2147483648" */
+#define MAX_KEY_LEN (24)
+
+/**
+ * Fill in buffer with a set_num/msg_num key string, given the numeric
+ * values. Numeric values must be >= 0. Buffer must be of length
+ * MAX_KEY_LEN or more.
+ */
+static char*
+_catkey(char* buffer, int32_t set_num, int32_t msg_num) {
+    int32_t i = 0;
+    i = T_CString_integerToString(buffer, set_num, 10);
+    buffer[i++] = SEPARATOR;
+    T_CString_integerToString(buffer+i, msg_num, 10);
+    return buffer;
+}
+
+U_CAPI u_nl_catd U_EXPORT2
+u_catopen(const char* name, const char* locale, UErrorCode* ec) {
+    return (u_nl_catd) ures_open(name, locale, ec);
+}
+
+U_CAPI void U_EXPORT2
+u_catclose(u_nl_catd catd) {
+    ures_close((UResourceBundle*) catd); /* may be NULL */
+}
+
+U_CAPI const UChar* U_EXPORT2
+u_catgets(u_nl_catd catd, int32_t set_num, int32_t msg_num,
+          const UChar* s,
+          int32_t* len, UErrorCode* ec) {
+
+    char key[MAX_KEY_LEN];
+    const UChar* result;
+
+    if (ec == NULL || U_FAILURE(*ec)) {
+        goto ERROR;
+    }
+
+    result = ures_getStringByKey((const UResourceBundle*) catd,
+                                 _catkey(key, set_num, msg_num),
+                                 len, ec);
+    if (U_FAILURE(*ec)) {
+        goto ERROR;
+    }
+
+    return result;
+
+ ERROR:
+    /* In case of any failure, return s */
+    if (len != NULL) {
+        *len = u_strlen(s);
+    }
+    return s;
+}
+
+/*eof*/
diff --git a/icu/source/common/uchar.c b/icu/source/common/uchar.c
new file mode 100644
index 0000000..d9f5f12
--- /dev/null
+++ b/icu/source/common/uchar.c
@@ -0,0 +1,865 @@
+/*
+********************************************************************************
+*   Copyright (C) 1996-2010, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+********************************************************************************
+*
+* File UCHAR.C
+*
+* Modification History:
+*
+*   Date        Name        Description
+*   04/02/97    aliu        Creation.
+*   4/15/99     Madhu       Updated all the function definitions for C Implementation
+*   5/20/99     Madhu       Added the function u_getVersion()
+*   8/19/1999   srl         Upgraded scripts to Unicode3.0 
+*   11/11/1999  weiv        added u_isalnum(), cleaned comments
+*   01/11/2000  helena      Renamed u_getVersion to u_getUnicodeVersion.
+*   06/20/2000  helena      OS/400 port changes; mostly typecast.
+******************************************************************************
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/uchar.h"
+#include "unicode/uscript.h"
+#include "unicode/udata.h"
+#include "umutex.h"
+#include "cmemory.h"
+#include "ucln_cmn.h"
+#include "utrie2.h"
+#include "udataswp.h"
+#include "uprops.h"
+
+#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
+
+/* dynamically loaded Unicode character properties -------------------------- */
+
+#define UCHAR_HARDCODE_DATA 1
+
+#if UCHAR_HARDCODE_DATA
+
+/* uchar_props_data.c is machine-generated by genprops --csource */
+#include "uchar_props_data.c"
+
+#else
+
+/*
+ * loaded uprops.dat -
+ * for a description of the file format, see icu/source/tools/genprops/store.c
+ */
+static const char DATA_NAME[] = "uprops";
+static const char DATA_TYPE[] = "icu";
+
+static UDataMemory *propsData=NULL;
+static UErrorCode dataErrorCode=U_ZERO_ERROR;
+
+static uint8_t formatVersion[4]={ 0, 0, 0, 0 };
+static UVersionInfo dataVersion={ 0, 0, 0, 0 };
+
+static UTrie propsTrie={ 0 }, propsVectorsTrie={ 0 };
+static const uint32_t *pData32=NULL, *propsVectors=NULL;
+static int32_t countPropsVectors=0, propsVectorsColumns=0;
+
+static int8_t havePropsData=0;     /*  == 0   ->  Data has not been loaded.
+                                    *   < 0   ->  Error occured attempting to load data.
+                                    *   > 0   ->  Data has been successfully loaded.
+                                    */
+
+/* index values loaded from uprops.dat */
+static int32_t indexes[UPROPS_INDEX_COUNT];
+
+static UBool U_CALLCONV
+isAcceptable(void *context,
+             const char *type, const char *name,
+             const UDataInfo *pInfo) {
+    if(
+        pInfo->size>=20 &&
+        pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
+        pInfo->charsetFamily==U_CHARSET_FAMILY &&
+        pInfo->dataFormat[0]==0x55 &&   /* dataFormat="UPro" */
+        pInfo->dataFormat[1]==0x50 &&
+        pInfo->dataFormat[2]==0x72 &&
+        pInfo->dataFormat[3]==0x6f &&
+        pInfo->formatVersion[0]==4 &&
+        pInfo->formatVersion[2]==UTRIE_SHIFT &&
+        pInfo->formatVersion[3]==UTRIE_INDEX_SHIFT
+    ) {
+        uprv_memcpy(formatVersion, pInfo->formatVersion, 4);
+        uprv_memcpy(dataVersion, pInfo->dataVersion, 4);
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+
+static UBool U_CALLCONV uchar_cleanup(void)
+{
+    if (propsData) {
+        udata_close(propsData);
+        propsData=NULL;
+    }
+    pData32=NULL;
+    propsVectors=NULL;
+    countPropsVectors=0;
+    uprv_memset(dataVersion, 0, U_MAX_VERSION_LENGTH);
+    dataErrorCode=U_ZERO_ERROR;
+    havePropsData=0;
+
+    return TRUE;
+}
+
+struct UCharProps {
+    UDataMemory *propsData;
+    UTrie propsTrie, propsVectorsTrie;
+    const uint32_t *pData32;
+};
+typedef struct UCharProps UCharProps;
+
+/* open uprops.icu */
+static void
+_openProps(UCharProps *ucp, UErrorCode *pErrorCode) {
+    const uint32_t *p;
+    int32_t length;
+
+    ucp->propsData=udata_openChoice(NULL, DATA_TYPE, DATA_NAME, isAcceptable, NULL, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        return;
+    }
+
+    ucp->pData32=p=(const uint32_t *)udata_getMemory(ucp->propsData);
+
+    /* unserialize the trie; it is directly after the int32_t indexes[UPROPS_INDEX_COUNT] */
+    length=(int32_t)p[UPROPS_PROPS32_INDEX]*4;
+    length=utrie_unserialize(&ucp->propsTrie, (const uint8_t *)(p+UPROPS_INDEX_COUNT), length-64, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        return;
+    }
+
+    /* unserialize the properties vectors trie */
+    length=(int32_t)(p[UPROPS_ADDITIONAL_VECTORS_INDEX]-p[UPROPS_ADDITIONAL_TRIE_INDEX])*4;
+    if(length>0) {
+        length=utrie_unserialize(&ucp->propsVectorsTrie, (const uint8_t *)(p+p[UPROPS_ADDITIONAL_TRIE_INDEX]), length, pErrorCode);
+    }
+    if(length<=0 || U_FAILURE(*pErrorCode)) {
+        /*
+         * length==0:
+         * Allow the properties vectors trie to be missing -
+         * also requires propsVectorsColumns=indexes[UPROPS_ADDITIONAL_VECTORS_COLUMNS_INDEX]
+         * to be zero so that this trie is never accessed.
+         */
+        uprv_memset(&ucp->propsVectorsTrie, 0, sizeof(ucp->propsVectorsTrie));
+    }
+}
+
+#endif
+
+#if !UCHAR_HARDCODE_DATA
+static int8_t
+uprv_loadPropsData(UErrorCode *pErrorCode) {
+    /* load Unicode character properties data from file if necessary */
+
+    /*
+     * This lazy intialization with double-checked locking (without mutex protection for
+     * haveNormData==0) is transiently unsafe under certain circumstances.
+     * Check the readme and use u_init() if necessary.
+     */
+    if(havePropsData==0) {
+        UCharProps ucp={ NULL };
+
+        if(U_FAILURE(*pErrorCode)) {
+            return havePropsData;
+        }
+
+        /* open the data outside the mutex block */
+        _openProps(&ucp, pErrorCode);
+
+        if(U_SUCCESS(*pErrorCode)) {
+            /* in the mutex block, set the data for this process */
+            umtx_lock(NULL);
+            if(propsData==NULL) {
+                propsData=ucp.propsData;
+                ucp.propsData=NULL;
+                pData32=ucp.pData32;
+                ucp.pData32=NULL;
+                uprv_memcpy(&propsTrie, &ucp.propsTrie, sizeof(propsTrie));
+                uprv_memcpy(&propsVectorsTrie, &ucp.propsVectorsTrie, sizeof(propsVectorsTrie));
+            }
+
+            /* initialize some variables */
+            uprv_memcpy(indexes, pData32, sizeof(indexes));
+
+            /* additional properties */
+            if(indexes[UPROPS_ADDITIONAL_VECTORS_INDEX]!=0) {
+                propsVectors=pData32+indexes[UPROPS_ADDITIONAL_VECTORS_INDEX];
+                countPropsVectors=indexes[UPROPS_RESERVED_INDEX]-indexes[UPROPS_ADDITIONAL_VECTORS_INDEX];
+                propsVectorsColumns=indexes[UPROPS_ADDITIONAL_VECTORS_COLUMNS_INDEX];
+            }
+
+            havePropsData=1;
+            umtx_unlock(NULL);
+        } else {
+            dataErrorCode=*pErrorCode;
+            havePropsData=-1;
+        }
+        ucln_common_registerCleanup(UCLN_COMMON_UCHAR, uchar_cleanup);
+
+        /* if a different thread set it first, then close the extra data */
+        udata_close(ucp.propsData); /* NULL if it was set correctly */
+    }
+
+    return havePropsData;
+}
+
+static int8_t 
+loadPropsData(void) {
+    UErrorCode   errorCode = U_ZERO_ERROR;
+    int8_t       retVal    = uprv_loadPropsData(&errorCode);
+    return retVal;
+}
+
+#endif
+
+/* constants and macros for access to the data ------------------------------ */
+
+/* getting a uint32_t properties word from the data */
+#if UCHAR_HARDCODE_DATA
+
+#define GET_PROPS(c, result) ((result)=UTRIE2_GET16(&propsTrie, c));
+
+#else
+
+#define HAVE_DATA (havePropsData>0 || loadPropsData()>0)
+#define GET_PROPS_UNSAFE(c, result) \
+    UTRIE_GET16(&propsTrie, c, result);
+#define GET_PROPS(c, result) \
+    if(HAVE_DATA) { \
+        GET_PROPS_UNSAFE(c, result); \
+    } else { \
+        (result)=0; \
+    }
+
+#endif
+
+U_CFUNC UBool
+uprv_haveProperties(UErrorCode *pErrorCode) {
+    if(U_FAILURE(*pErrorCode)) {
+        return FALSE;
+    }
+#if !UCHAR_HARDCODE_DATA
+    if(havePropsData==0) {
+        uprv_loadPropsData(pErrorCode);
+    }
+    if(havePropsData<0) {
+        *pErrorCode=dataErrorCode;
+        return FALSE;
+    }
+#endif
+    return TRUE;
+}
+
+/* API functions ------------------------------------------------------------ */
+
+/* Gets the Unicode character's general category.*/
+U_CAPI int8_t U_EXPORT2
+u_charType(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (int8_t)GET_CATEGORY(props);
+}
+
+/* Enumerate all code points with their general categories. */
+struct _EnumTypeCallback {
+    UCharEnumTypeRange *enumRange;
+    const void *context;
+};
+
+static uint32_t U_CALLCONV
+_enumTypeValue(const void *context, uint32_t value) {
+    return GET_CATEGORY(value);
+}
+
+static UBool U_CALLCONV
+_enumTypeRange(const void *context, UChar32 start, UChar32 end, uint32_t value) {
+    /* just cast the value to UCharCategory */
+    return ((struct _EnumTypeCallback *)context)->
+        enumRange(((struct _EnumTypeCallback *)context)->context,
+                  start, end+1, (UCharCategory)value);
+}
+
+U_CAPI void U_EXPORT2
+u_enumCharTypes(UCharEnumTypeRange *enumRange, const void *context) {
+    struct _EnumTypeCallback callback;
+
+    if(enumRange==NULL
+#if !UCHAR_HARDCODE_DATA
+        || !HAVE_DATA
+#endif
+    ) {
+        return;
+    }
+
+    callback.enumRange=enumRange;
+    callback.context=context;
+    utrie2_enum(&propsTrie, _enumTypeValue, _enumTypeRange, &callback);
+}
+
+/* Checks if ch is a lower case letter.*/
+U_CAPI UBool U_EXPORT2
+u_islower(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)(GET_CATEGORY(props)==U_LOWERCASE_LETTER);
+}
+
+/* Checks if ch is an upper case letter.*/
+U_CAPI UBool U_EXPORT2
+u_isupper(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)(GET_CATEGORY(props)==U_UPPERCASE_LETTER);
+}
+
+/* Checks if ch is a title case letter; usually upper case letters.*/
+U_CAPI UBool U_EXPORT2
+u_istitle(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)(GET_CATEGORY(props)==U_TITLECASE_LETTER);
+}
+
+/* Checks if ch is a decimal digit. */
+U_CAPI UBool U_EXPORT2
+u_isdigit(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)(GET_CATEGORY(props)==U_DECIMAL_DIGIT_NUMBER);
+}
+
+U_CAPI UBool U_EXPORT2
+u_isxdigit(UChar32 c) {
+    uint32_t props;
+
+    /* check ASCII and Fullwidth ASCII a-fA-F */
+    if(
+        (c<=0x66 && c>=0x41 && (c<=0x46 || c>=0x61)) ||
+        (c>=0xff21 && c<=0xff46 && (c<=0xff26 || c>=0xff41))
+    ) {
+        return TRUE;
+    }
+
+    GET_PROPS(c, props);
+    return (UBool)(GET_CATEGORY(props)==U_DECIMAL_DIGIT_NUMBER);
+}
+
+/* Checks if the Unicode character is a letter.*/
+U_CAPI UBool U_EXPORT2
+u_isalpha(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)((CAT_MASK(props)&U_GC_L_MASK)!=0);
+}
+
+U_CAPI UBool U_EXPORT2
+u_isUAlphabetic(UChar32 c) {
+    return (u_getUnicodeProperties(c, 1)&U_MASK(UPROPS_ALPHABETIC))!=0;
+}
+
+/* Checks if c is a letter or a decimal digit */
+U_CAPI UBool U_EXPORT2
+u_isalnum(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)((CAT_MASK(props)&(U_GC_L_MASK|U_GC_ND_MASK))!=0);
+}
+
+/**
+ * Checks if c is alphabetic, or a decimal digit; implements UCHAR_POSIX_ALNUM.
+ * @internal
+ */
+U_CFUNC UBool
+u_isalnumPOSIX(UChar32 c) {
+    return (UBool)(u_isUAlphabetic(c) || u_isdigit(c));
+}
+
+/* Checks if ch is a unicode character with assigned character type.*/
+U_CAPI UBool U_EXPORT2
+u_isdefined(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)(GET_CATEGORY(props)!=0);
+}
+
+/* Checks if the Unicode character is a base form character that can take a diacritic.*/
+U_CAPI UBool U_EXPORT2
+u_isbase(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)((CAT_MASK(props)&(U_GC_L_MASK|U_GC_N_MASK|U_GC_MC_MASK|U_GC_ME_MASK))!=0);
+}
+
+/* Checks if the Unicode character is a control character.*/
+U_CAPI UBool U_EXPORT2
+u_iscntrl(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)((CAT_MASK(props)&(U_GC_CC_MASK|U_GC_CF_MASK|U_GC_ZL_MASK|U_GC_ZP_MASK))!=0);
+}
+
+U_CAPI UBool U_EXPORT2
+u_isISOControl(UChar32 c) {
+    return (uint32_t)c<=0x9f && (c<=0x1f || c>=0x7f);
+}
+
+/* Some control characters that are used as space. */
+#define IS_THAT_CONTROL_SPACE(c) \
+    (c<=0x9f && ((c>=TAB && c<=CR) || (c>=0x1c && c <=0x1f) || c==NL))
+
+/* Java has decided that U+0085 New Line is not whitespace any more. */
+#define IS_THAT_ASCII_CONTROL_SPACE(c) \
+    (c<=0x1f && c>=TAB && (c<=CR || c>=0x1c))
+
+/* Checks if the Unicode character is a space character.*/
+U_CAPI UBool U_EXPORT2
+u_isspace(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)((CAT_MASK(props)&U_GC_Z_MASK)!=0 || IS_THAT_CONTROL_SPACE(c));
+}
+
+U_CAPI UBool U_EXPORT2
+u_isJavaSpaceChar(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)((CAT_MASK(props)&U_GC_Z_MASK)!=0);
+}
+
+/* Checks if the Unicode character is a whitespace character.*/
+U_CAPI UBool U_EXPORT2
+u_isWhitespace(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)(
+                ((CAT_MASK(props)&U_GC_Z_MASK)!=0 &&
+                    c!=NBSP && c!=FIGURESP && c!=NNBSP) || /* exclude no-break spaces */
+                IS_THAT_ASCII_CONTROL_SPACE(c)
+           );
+}
+
+U_CAPI UBool U_EXPORT2
+u_isblank(UChar32 c) {
+    if((uint32_t)c<=0x9f) {
+        return c==9 || c==0x20; /* TAB or SPACE */
+    } else {
+        /* Zs */
+        uint32_t props;
+        GET_PROPS(c, props);
+        return (UBool)(GET_CATEGORY(props)==U_SPACE_SEPARATOR);
+    }
+}
+
+U_CAPI UBool U_EXPORT2
+u_isUWhiteSpace(UChar32 c) {
+    return (u_getUnicodeProperties(c, 1)&U_MASK(UPROPS_WHITE_SPACE))!=0;
+}
+
+/* Checks if the Unicode character is printable.*/
+U_CAPI UBool U_EXPORT2
+u_isprint(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    /* comparing ==0 returns FALSE for the categories mentioned */
+    return (UBool)((CAT_MASK(props)&U_GC_C_MASK)==0);
+}
+
+/**
+ * Checks if c is in \p{graph}\p{blank} - \p{cntrl}.
+ * Implements UCHAR_POSIX_PRINT.
+ * @internal
+ */
+U_CFUNC UBool
+u_isprintPOSIX(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    /*
+     * The only cntrl character in graph+blank is TAB (in blank).
+     * Here we implement (blank-TAB)=Zs instead of calling u_isblank().
+     */
+    return (UBool)((GET_CATEGORY(props)==U_SPACE_SEPARATOR) || u_isgraphPOSIX(c));
+}
+
+U_CAPI UBool U_EXPORT2
+u_isgraph(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    /* comparing ==0 returns FALSE for the categories mentioned */
+    return (UBool)((CAT_MASK(props)&
+                    (U_GC_CC_MASK|U_GC_CF_MASK|U_GC_CS_MASK|U_GC_CN_MASK|U_GC_Z_MASK))
+                   ==0);
+}
+
+/**
+ * Checks if c is in
+ * [^\p{space}\p{gc=Control}\p{gc=Surrogate}\p{gc=Unassigned}]
+ * with space=\p{Whitespace} and Control=Cc.
+ * Implements UCHAR_POSIX_GRAPH.
+ * @internal
+ */
+U_CFUNC UBool
+u_isgraphPOSIX(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    /* \p{space}\p{gc=Control} == \p{gc=Z}\p{Control} */
+    /* comparing ==0 returns FALSE for the categories mentioned */
+    return (UBool)((CAT_MASK(props)&
+                    (U_GC_CC_MASK|U_GC_CS_MASK|U_GC_CN_MASK|U_GC_Z_MASK))
+                   ==0);
+}
+
+U_CAPI UBool U_EXPORT2
+u_ispunct(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)((CAT_MASK(props)&U_GC_P_MASK)!=0);
+}
+
+/* Checks if the Unicode character can start a Unicode identifier.*/
+U_CAPI UBool U_EXPORT2
+u_isIDStart(UChar32 c) {
+    /* same as u_isalpha() */
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)((CAT_MASK(props)&(U_GC_L_MASK|U_GC_NL_MASK))!=0);
+}
+
+/* Checks if the Unicode character can be a Unicode identifier part other than starting the
+ identifier.*/
+U_CAPI UBool U_EXPORT2
+u_isIDPart(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)(
+           (CAT_MASK(props)&
+            (U_GC_ND_MASK|U_GC_NL_MASK|
+             U_GC_L_MASK|
+             U_GC_PC_MASK|U_GC_MC_MASK|U_GC_MN_MASK)
+           )!=0 ||
+           u_isIDIgnorable(c));
+}
+
+/*Checks if the Unicode character can be ignorable in a Java or Unicode identifier.*/
+U_CAPI UBool U_EXPORT2
+u_isIDIgnorable(UChar32 c) {
+    if(c<=0x9f) {
+        return u_isISOControl(c) && !IS_THAT_ASCII_CONTROL_SPACE(c);
+    } else {
+        uint32_t props;
+        GET_PROPS(c, props);
+        return (UBool)(GET_CATEGORY(props)==U_FORMAT_CHAR);
+    }
+}
+
+/*Checks if the Unicode character can start a Java identifier.*/
+U_CAPI UBool U_EXPORT2
+u_isJavaIDStart(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)((CAT_MASK(props)&(U_GC_L_MASK|U_GC_SC_MASK|U_GC_PC_MASK))!=0);
+}
+
+/*Checks if the Unicode character can be a Java identifier part other than starting the
+ * identifier.
+ */
+U_CAPI UBool U_EXPORT2
+u_isJavaIDPart(UChar32 c) {
+    uint32_t props;
+    GET_PROPS(c, props);
+    return (UBool)(
+           (CAT_MASK(props)&
+            (U_GC_ND_MASK|U_GC_NL_MASK|
+             U_GC_L_MASK|
+             U_GC_SC_MASK|U_GC_PC_MASK|
+             U_GC_MC_MASK|U_GC_MN_MASK)
+           )!=0 ||
+           u_isIDIgnorable(c));
+}
+
+U_CAPI int32_t U_EXPORT2
+u_charDigitValue(UChar32 c) {
+    uint32_t props;
+    int32_t value;
+    GET_PROPS(c, props);
+    value=(int32_t)GET_NUMERIC_TYPE_VALUE(props)-UPROPS_NTV_DECIMAL_START;
+    if(value<=9) {
+        return value;
+    } else {
+        return -1;
+    }
+}
+
+U_CAPI double U_EXPORT2
+u_getNumericValue(UChar32 c) {
+    uint32_t props;
+    int32_t ntv;
+    GET_PROPS(c, props);
+    ntv=(int32_t)GET_NUMERIC_TYPE_VALUE(props);
+
+    if(ntv==UPROPS_NTV_NONE) {
+        return U_NO_NUMERIC_VALUE;
+    } else if(ntv<UPROPS_NTV_DIGIT_START) {
+        /* decimal digit */
+        return ntv-UPROPS_NTV_DECIMAL_START;
+    } else if(ntv<UPROPS_NTV_NUMERIC_START) {
+        /* other digit */
+        return ntv-UPROPS_NTV_DIGIT_START;
+    } else if(ntv<UPROPS_NTV_FRACTION_START) {
+        /* small integer */
+        return ntv-UPROPS_NTV_NUMERIC_START;
+    } else if(ntv<UPROPS_NTV_LARGE_START) {
+        /* fraction */
+        int32_t numerator=(ntv>>4)-12;
+        int32_t denominator=(ntv&0xf)+1;
+        return (double)numerator/denominator;
+    } else if(ntv<UPROPS_NTV_RESERVED_START) {
+        /* large, single-significant-digit integer */
+        double numValue;
+        int32_t mant=(ntv>>5)-14;
+        int32_t exp=(ntv&0x1f)+2;
+        numValue=mant;
+
+        /* multiply by 10^exp without math.h */
+        while(exp>=4) {
+            numValue*=10000.;
+            exp-=4;
+        }
+        switch(exp) {
+        case 3:
+            numValue*=1000.;
+            break;
+        case 2:
+            numValue*=100.;
+            break;
+        case 1:
+            numValue*=10.;
+            break;
+        case 0:
+        default:
+            break;
+        }
+
+        return numValue;
+    } else {
+        /* reserved */
+        return U_NO_NUMERIC_VALUE;
+    }
+}
+
+U_CAPI int32_t U_EXPORT2
+u_digit(UChar32 ch, int8_t radix) {
+    int8_t value;
+    if((uint8_t)(radix-2)<=(36-2)) {
+        value=(int8_t)u_charDigitValue(ch);
+        if(value<0) {
+            /* ch is not a decimal digit, try latin letters */
+            if(ch>=0x61 && ch<=0x7A) {
+                value=(int8_t)(ch-0x57);  /* ch - 'a' + 10 */
+            } else if(ch>=0x41 && ch<=0x5A) {
+                value=(int8_t)(ch-0x37);  /* ch - 'A' + 10 */
+            } else if(ch>=0xFF41 && ch<=0xFF5A) {
+                value=(int8_t)(ch-0xFF37);  /* fullwidth ASCII a-z */
+            } else if(ch>=0xFF21 && ch<=0xFF3A) {
+                value=(int8_t)(ch-0xFF17);  /* fullwidth ASCII A-Z */
+            }
+        }
+    } else {
+        value=-1;   /* invalid radix */
+    }
+    return (int8_t)((value<radix) ? value : -1);
+}
+
+U_CAPI UChar32 U_EXPORT2
+u_forDigit(int32_t digit, int8_t radix) {
+    if((uint8_t)(radix-2)>(36-2) || (uint32_t)digit>=(uint32_t)radix) {
+        return 0;
+    } else if(digit<10) {
+        return (UChar32)(0x30+digit);
+    } else {
+        return (UChar32)((0x61-10)+digit);
+    }
+}
+
+/* miscellaneous, and support for uprops.c ---------------------------------- */
+
+U_CAPI void U_EXPORT2
+u_getUnicodeVersion(UVersionInfo versionArray) {
+    if(versionArray!=NULL) {
+        uprv_memcpy(versionArray, dataVersion, U_MAX_VERSION_LENGTH);
+    }
+}
+
+U_CFUNC uint32_t
+u_getUnicodeProperties(UChar32 c, int32_t column) {
+    uint16_t vecIndex;
+
+    if(column==-1) {
+        uint32_t props;
+        GET_PROPS(c, props);
+        return props;
+    } else if(
+#if !UCHAR_HARDCODE_DATA
+               !HAVE_DATA || countPropsVectors==0 ||
+#endif
+               column<0 || column>=propsVectorsColumns
+    ) {
+        return 0;
+    } else {
+        vecIndex=UTRIE2_GET16(&propsVectorsTrie, c);
+        return propsVectors[vecIndex+column];
+    }
+}
+
+U_CFUNC int32_t
+uprv_getMaxValues(int32_t column) {
+#if !UCHAR_HARDCODE_DATA
+    if(HAVE_DATA) {
+#endif
+        switch(column) {
+        case 0:
+            return indexes[UPROPS_MAX_VALUES_INDEX];
+        case 2:
+            return indexes[UPROPS_MAX_VALUES_2_INDEX];
+        default:
+            return 0;
+        }
+#if !UCHAR_HARDCODE_DATA
+    } else {
+        return 0;
+    }
+#endif
+}
+
+U_CAPI void U_EXPORT2
+u_charAge(UChar32 c, UVersionInfo versionArray) {
+    if(versionArray!=NULL) {
+        uint32_t version=u_getUnicodeProperties(c, 0)>>UPROPS_AGE_SHIFT;
+        versionArray[0]=(uint8_t)(version>>4);
+        versionArray[1]=(uint8_t)(version&0xf);
+        versionArray[2]=versionArray[3]=0;
+    }
+}
+
+U_CAPI UScriptCode U_EXPORT2
+uscript_getScript(UChar32 c, UErrorCode *pErrorCode) {
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return USCRIPT_INVALID_CODE;
+    }
+    if((uint32_t)c>0x10ffff) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return USCRIPT_INVALID_CODE;
+    }
+
+    return (UScriptCode)(u_getUnicodeProperties(c, 0)&UPROPS_SCRIPT_MASK);
+}
+
+U_CAPI UBlockCode U_EXPORT2
+ublock_getCode(UChar32 c) {
+    return (UBlockCode)((u_getUnicodeProperties(c, 0)&UPROPS_BLOCK_MASK)>>UPROPS_BLOCK_SHIFT);
+}
+
+/* property starts for UnicodeSet ------------------------------------------- */
+
+static UBool U_CALLCONV
+_enumPropertyStartsRange(const void *context, UChar32 start, UChar32 end, uint32_t value) {
+    /* add the start code point to the USet */
+    const USetAdder *sa=(const USetAdder *)context;
+    sa->add(sa->set, start);
+    return TRUE;
+}
+
+#define USET_ADD_CP_AND_NEXT(sa, cp) sa->add(sa->set, cp); sa->add(sa->set, cp+1)
+
+U_CFUNC void U_EXPORT2
+uchar_addPropertyStarts(const USetAdder *sa, UErrorCode *pErrorCode) {
+    if(U_FAILURE(*pErrorCode)) {
+        return;
+    }
+
+#if !UCHAR_HARDCODE_DATA
+    if(!HAVE_DATA) {
+        *pErrorCode=dataErrorCode;
+        return;
+    }
+#endif
+
+    /* add the start code point of each same-value range of the main trie */
+    utrie2_enum(&propsTrie, NULL, _enumPropertyStartsRange, sa);
+
+    /* add code points with hardcoded properties, plus the ones following them */
+
+    /* add for u_isblank() */
+    USET_ADD_CP_AND_NEXT(sa, TAB);
+
+    /* add for IS_THAT_CONTROL_SPACE() */
+    sa->add(sa->set, CR+1); /* range TAB..CR */
+    sa->add(sa->set, 0x1c);
+    sa->add(sa->set, 0x1f+1);
+    USET_ADD_CP_AND_NEXT(sa, NL);
+
+    /* add for u_isIDIgnorable() what was not added above */
+    sa->add(sa->set, DEL); /* range DEL..NBSP-1, NBSP added below */
+    sa->add(sa->set, HAIRSP);
+    sa->add(sa->set, RLM+1);
+    sa->add(sa->set, INHSWAP);
+    sa->add(sa->set, NOMDIG+1);
+    USET_ADD_CP_AND_NEXT(sa, ZWNBSP);
+
+    /* add no-break spaces for u_isWhitespace() what was not added above */
+    USET_ADD_CP_AND_NEXT(sa, NBSP);
+    USET_ADD_CP_AND_NEXT(sa, FIGURESP);
+    USET_ADD_CP_AND_NEXT(sa, NNBSP);
+
+    /* add for u_digit() */
+    sa->add(sa->set, U_a);
+    sa->add(sa->set, U_z+1);
+    sa->add(sa->set, U_A);
+    sa->add(sa->set, U_Z+1);
+    sa->add(sa->set, U_FW_a);
+    sa->add(sa->set, U_FW_z+1);
+    sa->add(sa->set, U_FW_A);
+    sa->add(sa->set, U_FW_Z+1);
+
+    /* add for u_isxdigit() */
+    sa->add(sa->set, U_f+1);
+    sa->add(sa->set, U_F+1);
+    sa->add(sa->set, U_FW_f+1);
+    sa->add(sa->set, U_FW_F+1);
+
+    /* add for UCHAR_DEFAULT_IGNORABLE_CODE_POINT what was not added above */
+    sa->add(sa->set, WJ); /* range WJ..NOMDIG */
+    sa->add(sa->set, 0xfff0);
+    sa->add(sa->set, 0xfffb+1);
+    sa->add(sa->set, 0xe0000);
+    sa->add(sa->set, 0xe0fff+1);
+
+    /* add for UCHAR_GRAPHEME_BASE and others */
+    USET_ADD_CP_AND_NEXT(sa, CGJ);
+}
+
+U_CFUNC void U_EXPORT2
+upropsvec_addPropertyStarts(const USetAdder *sa, UErrorCode *pErrorCode) {
+    if(U_FAILURE(*pErrorCode)) {
+        return;
+    }
+
+#if !UCHAR_HARDCODE_DATA
+    if(!HAVE_DATA) {
+        *pErrorCode=dataErrorCode;
+        return;
+    }
+#endif
+
+    /* add the start code point of each same-value range of the properties vectors trie */
+    if(propsVectorsColumns>0) {
+        /* if propsVectorsColumns==0 then the properties vectors trie may not be there at all */
+        utrie2_enum(&propsVectorsTrie, NULL, _enumPropertyStartsRange, sa);
+    }
+}
diff --git a/icu/source/common/uchar_props_data.c b/icu/source/common/uchar_props_data.c
new file mode 100644
index 0000000..dd8e764
--- /dev/null
+++ b/icu/source/common/uchar_props_data.c
@@ -0,0 +1,2598 @@
+/*
+ * Copyright (C) 1999-2009, International Business Machines
+ * Corporation and others.  All Rights Reserved.
+ *
+ * file name: uchar_props_data.c
+ *
+ * machine-generated on: 2009-10-24
+ */
+
+static const UVersionInfo dataVersion={5,2,0,0};
+
+static const uint16_t propsTrie_index[16472]={
+0x39b,0x3a3,0x3ab,0x3b3,0x3cb,0x3d3,0x3db,0x3e3,0x3eb,0x3f3,0x3f9,0x401,0x409,0x411,0x419,0x421,
+0x427,0x42f,0x437,0x43f,0x442,0x44a,0x452,0x45a,0x462,0x46a,0x466,0x46e,0x476,0x47e,0x483,0x48b,
+0x493,0x49b,0x49f,0x4a7,0x4af,0x4b7,0x4bf,0x4c7,0x4c6,0x4ce,0x4d3,0x4db,0x4e1,0x4e9,0x4f1,0x4f9,
+0x501,0x509,0x511,0x519,0x51e,0x526,0x529,0x531,0x539,0x541,0x547,0x54f,0x54e,0x556,0x55e,0x566,
+0x56e,0x575,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x57d,0x57f,0x587,0x58f,0x597,0x59d,0x5a5,0x5ad,
+0x5b5,0x5bb,0x5c3,0x5cb,0x5d3,0x5d9,0x5e1,0x5e9,0x597,0x5f1,0x5f9,0x601,0x609,0x611,0x619,0x620,
+0x628,0x62e,0x636,0x63e,0x646,0x64c,0x654,0x65c,0x646,0x664,0x66c,0x674,0x67c,0x683,0x68b,0x693,
+0x509,0x69b,0x6a3,0x3bb,0x6ab,0x6b3,0x6bb,0x3bb,0x6c3,0x6cb,0x6d3,0x6d8,0x6e0,0x6e7,0x6ef,0x3bb,
+0x51e,0x6f7,0x6ff,0x707,0x70f,0x493,0x717,0x71b,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x723,0x51e,0x72b,0x72f,0x737,0x51e,0x73d,0x51e,0x743,0x74b,0x753,0x51e,0x51e,0x75b,
+0x763,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x768,0x770,0x51e,0x51e,0x778,0x780,0x788,0x790,0x798,0x51e,0x7a0,0x7a8,0x7b0,
+0x7b8,0x51e,0x7c0,0x7c2,0x51e,0x7ca,0x51e,0x7ce,0x7d6,0x7de,0x7e6,0x7eb,0x51e,0x7f3,0x7fb,0x803,
+0x80b,0x51e,0x813,0x81b,0x823,0x82b,0x3bb,0x3bb,0x833,0x836,0x83e,0x846,0x84e,0x856,0x3bb,0x3bb,
+0x51e,0x85e,0x866,0x86d,0x3bb,0x3bb,0x875,0x87d,0x43b,0x885,0x888,0x890,0x897,0x888,0x462,0x89f,
+0x3eb,0x3eb,0x3eb,0x3eb,0x8a7,0x3eb,0x3eb,0x3eb,0x8af,0x8b7,0x8bf,0x8c7,0x8cf,0x8d3,0x8db,0x8e3,
+0x8eb,0x8f3,0x8fb,0x903,0x90b,0x913,0x91a,0x922,0x92a,0x932,0x93a,0x942,0x94a,0x952,0x957,0x95d,
+0x962,0x962,0x962,0x962,0x962,0x962,0x962,0x962,0x96a,0x972,0x803,0x975,0x97d,0x984,0x989,0x991,
+0x803,0x999,0x9a1,0x9a9,0x9ac,0x803,0x803,0x9b3,0x803,0x803,0x803,0x803,0x803,0x9bb,0x9c3,0x9c5,
+0x803,0x803,0x803,0x9cd,0x803,0x803,0x9d2,0x9da,0x9e2,0x9e8,0x9ed,0x9f5,0x9fd,0xa03,0xa0b,0xa12,
+0x803,0x803,0x803,0x803,0x803,0x803,0x803,0x803,0x962,0x962,0x962,0x962,0xa1a,0x962,0xa21,0xa28,
+0x962,0x962,0x962,0x962,0x962,0x962,0x962,0x962,0x803,0x95e,0xa30,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x493,0xa38,0xa3c,0xa44,0x3eb,0x3eb,0x3eb,0xa4c,0x43b,0xa54,0x51e,0xa5b,0xa63,0xa6b,0xa6b,0x462,
+0xa73,0xa7b,0x3bb,0x3bb,0xa83,0x803,0x803,0xa8a,0x803,0x803,0x803,0x803,0x803,0x803,0xa92,0xa98,
+0xaa0,0xaa8,0x509,0x51e,0xab0,0x763,0x51e,0xab8,0xac0,0xac5,0x51e,0x51e,0xaca,0x7c2,0x803,0xad1,
+0xad9,0xae1,0xae5,0x803,0xae1,0xaed,0x803,0xad9,0x803,0x803,0x803,0x803,0x803,0x803,0x803,0x803,
+0xaf5,0x51e,0x51e,0x51e,0xafd,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0xb03,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xb08,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x7ce,0x803,0x803,
+0xb10,0x51e,0xb13,0x51e,0xb1b,0xb21,0xb29,0xb31,0xb36,0x51e,0x51e,0xb3a,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xb41,0x51e,0xb48,0xb4e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xb56,0x51e,0x51e,0x51e,0xb5e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xb60,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xb67,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0xb6e,0x51e,0x51e,0x51e,0xb75,0xb7d,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xb82,0x51e,0x51e,0xb8a,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xb8e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xb91,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xb94,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0xb9a,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0xba2,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0xba7,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0xbac,0x51e,0x51e,0x51e,0xbb1,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0xbb9,0xbc0,0xbc4,0x51e,0x51e,0x51e,0xbcb,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xbd1,0x3bb,
+0xbd9,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0xbdf,0x803,0xbe6,0x86d,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0xbeb,0xbf3,0x3eb,0xbfb,0xc03,0x51e,0x51e,0xc0b,0xc13,0xc1b,0x3eb,0xc20,0xc28,0x3bb,0x3bb,0xc2c,
+0xc34,0xc3c,0x51e,0xc44,0xc4c,0xc4f,0xc56,0xc5e,0x55e,0xc66,0xc6d,0x7d6,0x57d,0xc75,0xc7d,0x3bb,
+0x51e,0xc85,0xc8d,0xc95,0x51e,0xc9d,0xca5,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x51e,0xcad,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xcb5,0xcbc,0x7c1,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,
+0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0x51e,0x51e,0x51e,0xcd4,0x51e,0xbcc,0xcdb,0xce0,
+0x51e,0xce8,0x51e,0xce8,0x51e,0x51e,0xcec,0x3bb,0xcf4,0xcfc,0xd04,0x51e,0x51e,0xd08,0xd0d,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xd12,0xa5f,0x51e,0xd1a,0x51e,0xd20,0xd24,
+0xd2c,0xd34,0xd3b,0xd43,0x51e,0x51e,0x51e,0xd49,0xd51,0x3ab,0xd59,0xd61,0xd66,0xd6e,0xd76,0xd7e,
+0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,
+0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,0xcc4,
+0xeec,0xeec,0xf2c,0xf6c,0xfac,0xfe4,0x1024,0x1064,0x109c,0x10dc,0x1108,0x1148,0x1188,0x1198,0x11d8,0x120c,
+0x124c,0x127c,0x12bc,0x12fc,0x1318,0x134c,0x1384,0x13c4,0x1404,0x1444,0x1478,0x14a4,0x14e4,0x151c,0x1538,0x1578,
+0xa80,0xac0,0xafc,0xa40,0xb3c,0xa40,0xb7c,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xbbc,0xa40,0xa40,0xa40,0xbfc,0xa40,
+0xc3c,0xc73,0x1db,0x1db,0xc97,0xccb,0x1db,0xcf3,0x1db,0x1db,0x1db,0x1db,0xd20,0x1db,0x1db,0x1db,
+0x1db,0x1db,0x1db,0x1db,0xd34,0x1db,0xd6c,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xdac,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xdec,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,
+0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0xe2c,
+0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,
+0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0x700,0xe2c,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0xd86,0xd8d,0xd95,0x3bb,0x51e,0x51e,0x51e,0x4f5,0xd9d,0xda5,0xdad,0xdb5,0xdbc,0x3bb,0xdc3,0xdc7,
+0x3bb,0x3bb,0x3bb,0x3bb,0x7d6,0x51e,0xdcf,0x3bb,0xd6e,0xdd7,0xddf,0x3bb,0xde7,0x51e,0xdef,0x3bb,
+0x493,0x49d,0xdf7,0x51e,0x57e,0xdff,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0xe07,0xe0a,0xe12,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0xe1a,0xe22,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0xe2a,0xe31,0xe39,0xe41,0x3bb,0x3bb,0x3bb,0x3bb,0x51e,0xe49,0xe51,0xe59,0x3bb,0x3bb,0x3bb,0x3bb,
+0x51e,0x51e,0xe61,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0xe69,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x84e,0xe71,0xe79,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xe81,0x3bb,0x3bb,0x3bb,0x3bb,0xe89,0xe91,0xe99,0xea1,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xe81,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x803,0x803,0x803,0x803,
+0x803,0x803,0x803,0xa92,0x803,0xea9,0x803,0xeb0,0xeb8,0xebe,0xec2,0x3bb,0x803,0x803,0xeca,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x803,0x803,0xed2,0xeda,0x3bb,0x3bb,0x3bb,0x3bb,0xee2,0xee9,0xeee,0xef4,
+0xefc,0xf04,0xf0c,0xee6,0xf14,0xf1c,0xf24,0xf29,0xefb,0xee2,0xee9,0xee5,0xef4,0xf31,0xee3,0xf34,
+0xee6,0xf3c,0xf44,0xf4c,0xf53,0xf3f,0xf47,0xf4f,0xf56,0xf42,0xf5e,0xf66,0x803,0xf6e,0x803,0x803,
+0xa8a,0x3bb,0x3bb,0x3bb,0xf76,0xf7b,0xf83,0xf8b,0xf93,0x3bb,0x3bb,0x3bb,0xf97,0xa93,0xf9d,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0xfa5,0x51e,0x51e,0xfac,
+0x51e,0x51e,0x51e,0xfb4,0x51e,0xfbc,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xb72,0x51e,0x51e,0xfc4,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xfcc,0xfd4,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0xbb1,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xfdb,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xfe2,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0xfe9,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0xa63,0x3bb,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,
+0x51e,0x51e,0x51e,0x51e,0x51e,0x75b,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x51e,0x51e,0x51e,0x51e,
+0xfed,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x51e,0x57e,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0xff5,0xffd,0xffd,0xffd,
+0x3bb,0x3bb,0x3bb,0x3bb,0x462,0x462,0x462,0x462,0x462,0x462,0x462,0x1005,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0x100d,0xf,0xf,0xf,0xf,
+0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,
+0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xc,0x17,0x17,0x17,
+0x19,0x17,0x17,0x17,0x14,0x15,0x17,0x18,0x17,0x13,0x17,0x17,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,0x17,0x18,0x18,0x18,0x17,0x17,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,0x14,0x17,0x15,0x1a,0x16,0x1a,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,0x14,0x18,0x15,0x18,0xf,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xf,0xf,0xf,0xf,
+0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,
+0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xc,0x17,0x19,0x19,
+0x19,0x19,0x1b,0x1b,0x1a,0x1b,2,0x1c,0x18,0x10,0x1b,0x1a,0x1b,0x18,0x34b,0x38b,
+0x1a,2,0x1b,0x17,0x1a,0x30b,2,0x1d,0x34cb,0x344b,0x3ccb,0x17,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,0x18,1,1,1,1,1,1,1,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,0x18,2,2,2,2,2,2,2,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,2,1,2,1,2,1,2,1,2,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,1,2,1,
+2,1,2,2,2,1,1,2,1,2,1,1,2,1,1,1,
+2,2,1,1,1,1,2,1,1,2,1,1,1,2,2,2,
+1,1,2,1,1,2,1,2,1,2,1,1,2,1,2,2,
+1,2,1,1,2,1,1,1,2,1,2,1,1,2,2,5,
+1,2,2,2,5,5,5,5,1,3,2,1,3,2,1,3,
+2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,
+2,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,2,1,3,2,1,2,1,1,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+2,2,2,2,2,2,1,1,2,1,1,2,2,1,2,1,
+1,1,1,2,1,2,1,2,1,2,1,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,5,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,
+4,4,4,4,4,4,4,4,4,4,0x1a,0x1a,0x1a,0x1a,4,4,
+4,4,4,4,4,4,4,4,4,4,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,4,4,4,4,4,0x1a,0x1a,0x1a,
+0x1a,0x1a,0x1a,0x1a,4,0x1a,4,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,1,2,1,2,4,0x1a,1,2,
+0,0,4,2,2,2,0x17,0,0,0,0,0,0x1a,0x1a,1,0x17,
+1,1,1,0,1,0,1,1,2,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,
+1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,1,
+1,2,2,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,2,2,2,2,
+1,2,0x18,1,2,1,1,2,2,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,0x1b,6,
+6,6,6,6,7,7,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,1,2,1,
+2,1,2,1,2,1,2,1,2,1,2,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,0,0,
+0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,0,0,4,0x17,0x17,0x17,0x17,0x17,0x17,0,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,0,0x17,0x13,0,
+0,0,0,0,0,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,0x13,6,0x17,6,6,0x17,6,6,0x17,6,0,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,
+0,0,0,0,5,5,5,0x17,0x17,0,0,0,0,0,0,0,
+0,0,0,0,0x10,0x10,0x10,0x10,0,0,0x18,0x18,0x18,0x17,0x17,0x19,
+0x17,0x17,0x1b,0x1b,6,6,6,6,6,6,6,6,6,6,6,0x17,
+0,0,0x17,0x17,0,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,6,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,0x17,
+0x17,0x17,5,5,6,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,0x17,5,6,6,6,6,6,6,
+6,0x10,7,6,6,6,6,6,6,4,4,6,6,0x1b,6,6,
+6,6,5,5,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,5,5,
+5,0x1b,0x1b,5,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+0x17,0x17,0,0x10,5,6,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,0,0,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,
+6,6,6,6,6,6,6,6,6,5,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
+0x249,0x289,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,6,6,6,6,6,6,6,6,6,4,4,0x1b,0x17,
+0x17,0x17,4,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,
+6,6,4,6,6,6,6,6,4,6,6,6,4,6,6,6,
+6,6,0,0,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+0x17,0x17,0x17,0,6,6,6,8,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0,0,6,5,8,8,8,6,6,6,
+6,6,6,6,6,8,8,8,8,6,8,0,5,6,6,6,
+6,6,0,0,5,5,5,5,5,5,5,5,5,5,6,6,
+0x17,0x17,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,4,5,0,
+0,0,0,0,0,5,5,5,5,5,5,5,0,6,8,8,
+0,5,5,5,5,5,5,5,5,0,0,5,5,0,0,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,
+5,5,5,5,5,0,5,0,0,0,5,5,5,5,0,0,
+6,5,8,8,8,6,6,6,6,0,0,8,8,0,0,8,
+8,6,5,0,0,0,0,0,0,0,0,8,0,0,0,0,
+5,5,0,5,5,5,6,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,
+0x1c9,0x209,0x249,0x289,5,5,0x19,0x19,0x37cb,0x35cb,0x3fcb,0x34cb,0x3ccb,0x94b,0x1b,0x19,
+0,0,0,0,0,6,6,8,0,5,5,5,5,5,5,0,
+0,0,0,5,5,0,0,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,0,5,5,5,5,5,5,5,0,5,5,
+0,5,5,0,5,5,0,0,6,0,8,8,8,6,6,0,
+0,0,0,6,6,0,0,6,6,6,0,0,0,6,0,0,
+0,0,0,0,0,5,5,5,5,0,5,0,0,0,0,0,
+0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,6,6,5,5,
+5,6,0,0,0,0,0,0,0,0,0,0,0,6,6,8,
+0,5,5,5,5,5,5,5,5,5,0,5,5,5,0,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,
+5,5,5,5,5,0,5,5,0,5,5,5,5,5,0,0,
+6,5,8,8,8,6,6,6,6,6,0,6,6,8,0,8,
+8,6,0,0,5,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,5,5,6,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,
+0x1c9,0x209,0x249,0x289,0,0x19,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,0,5,5,
+5,5,5,5,5,0,5,5,0,5,5,5,5,5,0,0,
+6,5,8,6,8,6,6,6,6,0,0,8,8,0,0,8,
+8,6,0,0,0,0,0,0,0,0,6,8,0,0,0,0,
+5,5,0,5,5,5,6,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,
+0x1c9,0x209,0x249,0x289,0x1b,5,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,6,5,0,5,5,5,5,5,5,0,
+0,0,5,5,5,0,5,5,5,5,0,0,0,5,5,0,
+5,0,5,5,0,0,0,5,5,0,0,0,5,5,5,0,
+0,0,5,5,5,5,5,5,5,5,5,5,5,5,0,0,
+0,0,8,8,6,8,8,0,0,0,8,8,8,0,8,8,
+8,6,0,0,5,0,0,0,0,0,0,8,0,0,0,0,
+0,0,0,0,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,
+0x7cb,0x1e4b,0x784b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x19,0x1b,0,0,0,0,0,
+0,8,8,8,0,5,5,5,5,5,5,5,5,0,5,5,
+5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,0,5,5,5,5,5,5,5,5,5,5,0,5,5,5,
+5,5,0,0,0,5,6,6,6,8,8,8,8,0,6,6,
+6,0,6,6,6,6,0,0,0,0,0,0,0,6,6,0,
+5,5,0,0,0,0,0,0,5,5,6,6,0,0,0x49,0x89,
+0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,0,0,
+0x54b,0x58b,0x5cb,0x60b,0x58b,0x5cb,0x60b,0x1b,0,0,8,8,0,5,5,5,
+5,5,5,5,5,0,5,5,5,0,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,
+5,5,5,5,0,5,5,5,5,5,0,0,6,5,8,6,
+8,8,8,8,8,0,6,8,8,0,8,8,6,6,0,0,
+0,0,0,0,0,8,8,0,0,0,0,0,0,0,5,0,
+5,5,6,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,
+0,0x1b,0x1b,0,0,0,0,0,0,0,0,0,0,0,0,0,
+5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0,0,0,5,8,8,
+8,6,6,6,6,0,8,8,8,0,8,8,8,6,0,0,
+0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,
+5,5,6,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,
+0x7cb,0x1e4b,0x784b,0x34cb,0x344b,0x3ccb,0,0,0,0x1b,5,5,5,5,5,5,
+0,0,8,8,0,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,0,0,0,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,
+5,5,5,5,5,5,5,5,0,5,0,0,5,5,5,5,
+5,5,5,0,0,0,6,0,0,0,0,8,8,8,6,6,
+6,0,6,0,8,8,8,8,8,8,8,8,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,
+0x17,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,6,5,5,
+6,6,6,6,6,6,6,0,0,0,0,0x19,5,5,5,5,
+5,5,4,6,6,6,6,6,6,6,6,0x17,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,0x17,0,0,0,0,0,5,5,0,
+5,0,0,5,5,0,5,0,0,5,0,0,0,0,0,0,
+5,5,5,5,0,5,5,5,5,5,5,5,0,5,5,5,
+0,5,0,5,0,0,5,5,0,5,5,5,5,6,5,5,
+6,6,6,6,6,6,0,6,6,5,0,0,5,5,5,5,
+5,0,4,0,6,6,6,6,6,6,0,0,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,5,5,0,0,5,0x1b,0x1b,0x1b,
+0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x1b,
+0x1b,0x1b,0x1b,0x1b,6,6,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,0x344b,0x3c4b,0x444b,0x4c4b,0x544b,0x5c4b,0x644b,0x6c4b,0x744b,0x2c4b,
+0x1b,6,0x1b,6,0x1b,6,0x14,0x15,0x14,0x15,8,8,5,5,5,5,
+5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,
+0,6,6,6,6,6,6,6,6,6,6,6,6,6,6,8,
+6,6,6,6,6,0x17,6,6,5,5,5,5,0,0,0,0,
+6,6,6,6,6,6,6,6,0,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,6,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,6,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,0x17,0x17,0x17,0x17,
+0x17,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,8,8,6,6,6,6,8,6,6,
+6,6,6,6,8,6,6,8,8,6,6,5,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,0x17,0x17,0x17,0x17,0x17,5,5,5,5,
+5,5,8,8,6,6,5,5,5,5,6,6,6,5,8,8,
+8,5,5,8,8,8,8,8,8,8,5,5,5,6,6,6,
+6,5,5,5,5,5,5,5,5,5,5,5,5,5,6,8,
+8,6,6,8,8,8,8,8,8,6,5,8,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,8,8,8,6,0x1b,0x1b,1,1,1,1,
+1,1,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,0x17,4,0,0,0,5,5,5,5,
+5,5,5,5,5,0,5,5,5,5,0,0,5,5,5,5,
+5,5,5,0,5,0,5,5,5,5,0,0,5,5,5,5,
+5,5,5,5,5,0,5,5,5,5,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,
+5,5,0,0,5,5,5,5,5,5,5,0,5,0,5,5,
+5,5,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,0,5,5,5,5,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,0,0,0,0,6,0x1b,0x17,0x17,0x17,
+0x17,0x17,0x17,0x17,0x17,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0xa4b,
+0xccb,0xf4b,0x11cb,0x144b,0x16cb,0x194b,0x1bcb,0x1e4b,0x788b,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,0,0,0,0,0,0,0,0,0,0,0,0x13,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0x17,0x17,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+0xc,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,0x14,0x15,0,0,0,
+5,5,5,5,5,5,5,5,5,5,5,0x17,0x17,0x17,0x98a,0x9ca,
+0xa0a,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,
+5,5,6,6,6,0,0,0,0,0,0,0,0,0,0,0,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,6,6,6,0x17,0x17,0,0,0,0,0,0,0,0,0,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,6,6,0,0,0,0,0,0,0,0,0,0,0,0,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,5,
+5,0,6,6,0,0,0,0,0,0,0,0,0,0,0,0,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0x10,0x10,8,6,6,6,6,6,6,6,8,8,
+8,8,8,8,8,8,6,8,8,6,6,6,6,6,6,6,
+6,6,6,6,0x17,0x17,0x17,4,0x17,0x17,0x17,0x19,5,6,0,0,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,
+0x54b,0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,0,0,0,0,0,0,
+0x17,0x17,0x17,0x17,0x17,0x17,0x13,0x17,0x17,0x17,0x17,6,6,6,0xc,0,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,
+5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,6,5,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,
+0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,0,0,0,6,6,6,8,8,8,8,6,
+6,8,8,8,0,0,0,0,8,8,6,8,8,8,8,8,
+8,6,6,6,0,0,0,0,0x1b,0,0,0,0x17,0x17,0x49,0x89,
+0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0,0,5,5,5,5,
+5,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,0,0,0,0,8,8,8,8,
+8,8,8,8,8,8,8,8,8,8,8,8,8,5,5,5,
+5,5,5,5,8,8,0,0,0,0,0,0,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,0x89,0,0,0,0x17,0x17,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,6,6,8,8,8,0,0,0x17,0x17,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,8,6,8,6,6,6,6,6,6,6,0,6,8,6,8,
+8,6,6,6,6,6,6,6,6,8,8,8,8,8,8,6,
+6,6,6,6,6,6,6,6,6,0,0,6,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,0x17,0x17,0x17,0x17,
+0x17,0x17,0x17,4,0x17,0x17,0x17,0x17,0x17,0x17,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,6,6,6,6,
+8,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,6,8,6,6,
+6,6,6,8,6,8,8,8,8,8,6,8,8,5,5,5,
+5,5,5,5,0,0,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
+0x249,0x289,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,6,6,6,6,6,6,6,6,6,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,6,6,8,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,8,6,6,6,6,8,8,
+6,6,8,0,0,0,5,5,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
+0x249,0x289,0,0,0,0,0,0,5,5,5,5,8,8,8,8,
+8,8,8,8,6,6,6,6,6,6,6,6,8,8,6,6,
+0,0,0,0x17,0x17,0x17,0x17,0x17,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
+0x249,0x289,0,0,0,5,5,5,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
+0x249,0x289,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,
+4,4,0x17,0x17,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,6,6,6,0x17,6,6,6,6,6,6,6,6,
+6,6,6,6,6,8,6,6,6,6,6,6,6,5,5,5,
+5,6,5,5,5,5,8,0,0,0,0,0,0,0,0,0,
+0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,
+4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,4,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,4,4,4,4,4,6,6,6,6,
+6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,6,6,6,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,
+2,2,2,2,1,1,1,1,1,1,1,1,2,2,2,2,
+2,2,0,0,1,1,1,1,1,1,0,0,2,2,2,2,
+2,2,2,2,1,1,1,1,1,1,1,1,2,2,2,2,
+2,2,2,2,1,1,1,1,1,1,1,1,2,2,2,2,
+2,2,0,0,1,1,1,1,1,1,0,0,2,2,2,2,
+2,2,2,2,0,1,0,1,0,1,0,1,2,2,2,2,
+2,2,2,2,1,1,1,1,1,1,1,1,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,
+2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,
+2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,
+2,0,2,2,1,1,1,1,3,0x1a,2,0x1a,0x1a,0x1a,2,2,
+2,0,2,2,1,1,1,1,3,0x1a,0x1a,0x1a,2,2,2,2,
+0,0,2,2,1,1,1,1,0,0x1a,0x1a,0x1a,2,2,2,2,
+2,2,2,2,1,1,1,1,1,0x1a,0x1a,0x1a,0,0,2,2,
+2,0,2,2,1,1,1,1,3,0x1a,0x1a,0,0xc,0xc,0xc,0xc,
+0xc,0xc,0xc,0xc,0xc,0xc,0xc,0x10,0x10,0x10,0x10,0x10,0x13,0x13,0x13,0x13,
+0x13,0x13,0x17,0x17,0x1c,0x1d,0x14,0x1c,0x1c,0x1d,0x14,0x1c,0x17,0x17,0x17,0x17,
+0x17,0x17,0x17,0x17,0xd,0xe,0x10,0x10,0x10,0x10,0x10,0xc,0x17,0x17,0x17,0x17,
+0x17,0x17,0x17,0x17,0x17,0x1c,0x1d,0x17,0x17,0x17,0x17,0x16,0x16,0x17,0x17,0x17,
+0x18,0x14,0x15,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x18,0x17,
+0x16,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0xc,0x10,0x10,0x10,0x10,
+0x10,0,0,0,0,0,0x10,0x10,0x10,0x10,0x10,0x10,0x2cb,4,0,0,
+0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x18,0x18,0x18,0x14,0x15,4,0x2cb,0x30b,0x34b,0x38b,
+0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x18,0x18,0x18,0x14,0x15,0,4,4,4,4,
+4,0,0,0,0,0,0,0,0,0,0,0,0x19,0x19,0x19,0x19,
+0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,0x19,
+0x19,0x19,0x19,0x19,0x19,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,6,
+6,6,6,6,6,7,7,7,7,6,7,7,7,6,6,6,
+6,6,6,6,6,6,6,6,6,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x1b,0x1b,1,0x1b,0x1b,0x1b,0x1b,1,
+0x1b,0x1b,2,1,1,1,2,2,1,1,1,2,0x1b,1,0x1b,0x1b,
+0x1b,1,1,1,1,1,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,1,0x1b,1,0x1b,
+1,0x1b,1,1,1,1,0x1b,2,1,1,1,1,2,5,5,5,
+5,2,0x1b,0x1b,2,2,1,1,0x18,0x18,0x18,0x18,0x18,1,2,2,
+2,2,0x1b,0x18,0x1b,0x1b,2,0x1b,0x358b,0x360b,0x364b,0x348b,0x388b,0x350b,0x390b,0x3d0b,
+0x410b,0x354b,0x454b,0x35cb,0x3dcb,0x45cb,0x4dcb,0x58b,0x58a,0x5ca,0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,
+0x78a,0x7ca,0x80a,0x84a,0x11ca,0x1e4a,0x980a,0x784a,0x58a,0x5ca,0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,
+0x78a,0x7ca,0x80a,0x84a,0x11ca,0x1e4a,0x980a,0x784a,0x784a,0x984a,0x788a,1,2,0x6ca,0x11ca,0x988a,
+0x78ca,0x54b,0,0,0,0,0,0,0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x18,0x1b,0x1b,0x18,0x1b,0x1b,0x18,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x1b,0x1b,0x18,0x1b,
+0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x18,0x18,0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x14,0x15,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x18,0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0x80b,0x84b,
+0x88b,0x8cb,0x90b,0x94b,0x98b,0x9cb,0xa0b,0xa4b,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,
+0x50b,0x7cb,0x80b,0x84b,0x88b,0x8cb,0x90b,0x94b,0x98b,0x9cb,0xa0b,0xa4b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x2cb,0x80b,0x84b,0x88b,0x8cb,0x90b,0x94b,0x98b,0x9cb,0xa0b,
+0xa4b,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0x2cb,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0,0,0,0,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,
+0x1b,0x1b,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0,0x1b,0,0x1b,0x1b,0x1b,0x1b,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x14,0x15,0x14,0x15,
+0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,
+0x48b,0x4cb,0x50b,0x7cb,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0x30b,0x34b,
+0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0x1b,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x18,0x18,0x18,0x18,
+0x18,0x14,0x15,0x18,0x18,0x18,0x18,0,0x18,0,0,0,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x14,0x15,
+0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x14,0x15,0x14,0x15,0x14,
+0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,
+0x15,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x14,0x15,0x14,0x15,
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x14,0x15,0x18,0x18,
+0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0,0,0,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,
+1,2,1,1,1,2,2,1,2,1,2,1,2,1,1,1,
+1,2,1,2,2,1,2,2,2,2,2,2,2,4,1,1,
+1,2,1,2,2,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,1,2,1,2,6,
+6,6,0,0,0,0,0,0,0,0x17,0x17,0x17,0x17,0x344b,0x17,0x17,
+2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,0,0,0,0,0,0,0,0,0,4,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,0,5,5,5,5,5,5,5,0,5,5,5,5,
+5,5,5,0,5,5,5,5,5,5,5,0,0x17,0x17,0x1c,0x1d,
+0x1c,0x1d,0x17,0x17,0x17,0x1c,0x1d,0x17,0x1c,0x1d,0x17,0x17,0x17,0x17,0x17,0x17,
+0x17,0x17,0x17,0x13,0x17,0x17,0x13,0x17,0x1c,0x1d,0x17,0x17,0x1c,0x1d,0x14,0x15,
+0x14,0x15,0x14,0x15,0x14,0x15,0x17,0x17,0x17,0x17,0x17,4,0x17,0x17,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,
+0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,
+0xc,0x17,0x17,0x17,0x1b,4,5,0x54a,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,
+0x14,0x15,0x1b,0x1b,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x13,0x14,0x15,0x15,
+0x1b,0x58a,0x5ca,0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,6,6,6,6,6,6,
+0x13,4,4,4,4,4,0x1b,0x1b,0x7ca,0xa4a,0xcca,4,5,0x17,0x1b,0x1b,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,0,0,6,6,0x1a,0x1a,4,4,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,0x17,4,4,4,5,
+0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,0,0,0,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,0,0x1b,0x1b,0x58b,0x5cb,0x60b,0x64b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0,0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,0x74b,0x78b,0x7cb,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0xa8b,0xacb,0xb0b,0xb4b,0xb8b,0xbcb,0xc0b,0xc4b,0xc8b,0xccb,0xd0b,
+0xd4b,0xd8b,0xdcb,0xe0b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0xe4b,0xe8b,0xecb,0xf0b,0xf4b,0xf8b,0xfcb,0x100b,0x104b,0x108b,0x10cb,
+0x110b,0x114b,0x118b,0x11cb,5,5,5,5,5,0x685,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,0x5c5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0x685,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0x705,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+0x585,5,5,0x705,5,5,5,0x7885,5,0x605,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0x785,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,0x5c5,5,5,5,5,5,5,5,
+0x685,5,0x645,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,0x7985,0x7c5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,0x7845,5,5,5,5,5,5,5,5,0x605,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,0x685,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,0x1e45,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,0x7985,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0x7a85,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,0x5c5,5,0x745,5,0x6c5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0x7c5,5,0x7845,0xa45,0xcc5,5,5,
+5,5,5,5,0xf45,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0x605,0x605,0x605,0x605,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,0x645,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0x585,5,5,
+5,5,5,5,5,0x585,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,0x585,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,0x785,0xa45,5,5,5,5,5,5,5,5,5,5,5,5,
+0x585,0x5c5,0x605,5,0x5c5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0x7c5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0x745,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0x705,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0x785,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0x1e45,5,5,5,5,5,5,5,0x645,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,0x7885,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x5c5,5,
+5,5,5,0x5c5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0x5c5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,0x7845,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0x6c5,5,5,5,5,5,0x1e45,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,0x6c5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,0x545,5,5,5,5,5,5,5,5,5,5,5,5,5,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,
+0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,4,0x17,0x17,0x17,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,5,5,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,
+1,2,1,2,1,2,1,2,1,2,5,6,7,7,7,0x17,
+0,0,0,0,0,0,0,0,6,6,0x17,4,1,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+1,2,1,2,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,0x58a,0x5ca,0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0x54a,6,6,0x17,0x17,
+0x17,0x17,0x17,0x17,0,0,0,0,0,0,0,0,0x1a,0x1a,0x1a,0x1a,
+0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
+0x1a,0x1a,0x1a,4,4,4,4,4,4,4,4,4,0x1a,0x1a,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,2,2,1,2,
+1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
+4,2,2,2,2,2,2,2,2,1,2,1,2,1,1,2,
+1,2,1,2,1,2,1,2,4,0x1a,0x1a,1,2,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,
+5,5,6,5,5,5,6,5,5,5,5,6,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,8,8,6,6,8,0x1b,0x1b,0x1b,0x1b,0,0,0,0,
+0x34cb,0x344b,0x3ccb,0x37cb,0x35cb,0x3fcb,0x1b,0x1b,0x19,0x1b,0,0,0,0,0,0,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0x17,0x17,0x17,0x17,0,0,0,0,0,0,0,0,
+8,8,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+8,8,8,8,8,8,8,8,8,8,8,8,6,0,0,0,
+0,0,0,0,0,0,0x17,0x17,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,
+0x249,0x289,0,0,0,0,0,0,6,6,6,6,6,6,6,6,
+6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,
+0x17,0x17,0x17,5,0,0,0,0,5,5,5,5,5,5,6,6,
+6,6,6,6,6,6,0x17,0x17,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,
+6,6,6,6,6,6,8,8,0,0,0,0,0,0,0,0,
+0,0,0,0x17,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,6,8,8,6,6,6,6,8,8,
+6,8,8,8,8,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+0x17,0x17,0,4,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,
+0,0,0x17,0x17,5,5,5,5,5,5,5,5,5,6,6,6,
+6,6,6,8,8,6,6,8,8,6,6,0,0,0,0,0,
+0,0,0,0,5,5,5,6,5,5,5,5,5,5,5,5,
+6,8,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,
+0x17,0x17,0x17,0x17,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,4,5,5,5,5,5,5,0x1b,0x1b,0x1b,5,8,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,6,5,6,6,6,5,5,6,6,5,5,5,
+5,5,6,6,5,6,5,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,
+5,4,0x17,0x17,5,5,5,8,8,6,8,8,6,8,8,0x17,
+8,6,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,
+0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,0,0,0,0,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
+0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+5,5,5,5,5,5,5,5,5,5,5,0x605,5,5,5,5,
+5,5,5,0x7c5,5,5,5,5,0x5c5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0x6c5,5,0x6c5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0x7c5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,
+2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,
+0,0,0,2,2,2,2,2,0,0,0,0,0,5,6,5,
+5,5,5,5,5,5,5,5,5,0x18,5,5,5,5,5,5,
+5,5,5,5,5,5,5,0,5,5,5,5,5,0,5,0,
+5,5,0,5,5,0,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,0x14,0x15,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,0,0,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+5,5,5,5,5,5,5,5,5,5,5,5,0x19,0x1b,0,0,
+6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x14,0x15,0x17,0,0,0,0,0,0,
+6,6,6,6,6,6,6,0,0,0,0,0,0,0,0,0,
+0x17,0x13,0x13,0x16,0x16,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,0x15,0x14,
+0x15,0x17,0x17,0x14,0x15,0x17,0x17,0x17,0x17,0x16,0x16,0x16,0x17,0x17,0x17,0,
+0x17,0x17,0x17,0x17,0x13,0x14,0x15,0x14,0x15,0x14,0x15,0x17,0x17,0x17,0x18,0x13,
+0x18,0x18,0x18,0,0x17,0x19,0x17,0x17,0,0,0,0,5,5,5,5,
+5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,0,0,0x10,0,0x17,0x17,0x17,0x19,0x17,0x17,0x17,0x14,0x15,0x17,0x18,
+0x17,0x13,0x17,0x17,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x17,0x17,
+0x18,0x18,0x18,0x17,0x1a,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0x14,
+0x18,0x15,0x18,0x14,0x15,0x17,0x14,0x15,0x17,0x17,5,5,5,5,5,5,
+5,5,5,5,4,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,4,4,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,0,0,0,5,5,5,5,5,5,
+0,0,5,5,5,5,5,5,0,0,5,5,5,5,5,5,
+0,0,5,5,5,0,0,0,0x19,0x19,0x18,0x1a,0x1b,0x19,0x19,0,
+0x1b,0x18,0x18,0x18,0x18,0x1b,0x1b,0,0,0,0,0,0,0,0,0,
+0,0x10,0x10,0x10,0x1b,0x1b,0,0,5,5,5,5,5,5,5,5,
+5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,
+5,5,0,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,0,0,0x17,0x17,0x1b,0,0,0,0,0x58b,0x5cb,0x60b,0x64b,0x68b,
+0x6cb,0x70b,0x74b,0x78b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,0x16cb,0x194b,0x1bcb,0x1e4b,0x800b,0x880b,
+0x900b,0x980b,0xa00b,0xa80b,0xb00b,0xb80b,0x784b,0x804b,0x884b,0x904b,0x984b,0xa04b,0xa84b,0xb04b,0xb84b,0x788b,
+0x808b,0x888b,0x908b,0x988b,0xa08b,0xa88b,0xb08b,0xb88b,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x34ca,0x344a,0x58a,0x68a,0x11ca,0x980a,0x984a,0x988a,0x68a,0x7ca,0x11ca,0x1e4a,
+0x980a,0x784a,0x984a,0x68a,0x7ca,0x11ca,0x1e4a,0x980a,0x784a,0x788a,0x988a,0x7ca,0x58a,0x58a,0x58a,0x5ca,
+0x5ca,0x5ca,0x5ca,0x68a,0x7ca,0x7ca,0x7ca,0x7ca,0x7ca,0xcca,0x11ca,0x11ca,0x11ca,0x11ca,0x1e4a,0x880a,
+0x980a,0x980a,0x980a,0x980a,0x980a,0x784a,0x984a,0x68a,0x11ca,0x344b,0x344b,0x388b,0x3ccb,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x54b,0,0,0,0,0,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,6,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x58b,0x68b,0x7cb,0x11cb,
+0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0x1bca,5,5,
+5,5,5,5,5,5,0xb80a,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0,0x17,5,5,5,5,
+0,0,0,0,5,5,5,5,5,5,5,5,0x17,0x58a,0x5ca,0x7ca,
+0xa4a,0x1e4a,0,0,0,0,0,0,0,0,0,0,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,0x49,0x89,0xc9,0x109,
+0x149,0x189,0x1c9,0x209,0x249,0x289,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,
+5,5,0,0,5,0,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,5,
+5,0,0,0,5,0,0,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0x17,
+0x58b,0x5cb,0x60b,0x7cb,0xa4b,0x1e4b,0x784b,0x788b,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,0x58b,0x7cb,
+0xa4b,0x1e4b,0x5cb,0x60b,0,0,0,0x17,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,0,0,0,0,0,0x17,5,6,6,6,0,6,6,0,
+0,0,0,0,6,6,6,6,5,5,5,5,0,5,5,5,
+0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,0,0,0,0,6,6,6,0,
+0,0,0,6,0x30b,0x34b,0x38b,0x3cb,0x7cb,0xa4b,0x1e4b,0x784b,0,0,0,0,
+0,0,0,0,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,0x58b,0x11cb,0x17,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0,0,0,0x17,0x17,0x17,
+0x17,0x17,0x17,0x17,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0,0,0x58b,0x5cb,0x60b,0x64b,
+0x7cb,0xa4b,0x1e4b,0x784b,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,0,0,0,0,0,0x58b,0x5cb,0x60b,0x64b,
+0x7cb,0xa4b,0x1e4b,0x784b,5,5,5,5,5,5,5,5,5,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,0x48b,0x4cb,0x50b,0x7cb,0xa4b,0xccb,
+0xf4b,0x11cb,0x144b,0x16cb,0x194b,0x1bcb,0x1e4b,0x800b,0x880b,0x900b,0x980b,0xa00b,0xa80b,0xb00b,0xb80b,0x344b,
+0x34cb,0x348b,0x388b,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,8,8,8,6,6,6,6,8,8,6,6,0x17,
+0x17,0x10,0x17,0x17,0x17,0x17,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x5ca,0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0x60a,0x64a,0x68a,0x6ca,
+0x70a,0x74a,0x78a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,0x58a,0x5ca,0x60a,0x64a,0x68a,0x6ca,0x70a,
+0x74a,0x78a,0x58a,0x5ca,0x60a,0x64a,0x68a,0x5ca,0x60a,0x60a,0x64a,0x68a,0x6ca,0x70a,0x74a,0x78a,
+0x58a,0x5ca,0x60a,0x60a,0x64a,0x68a,0xa,0xa,0x58a,0x5ca,0x60a,0x60a,0x64a,0x68a,0x60a,0x60a,
+0x64a,0x64a,0x64a,0x64a,0x6ca,0x70a,0x70a,0x70a,0x74a,0x74a,0x78a,0x78a,0x78a,0x78a,0x5ca,0x60a,
+0x64a,0x68a,0x6ca,0x58a,0x5ca,0x60a,0x64a,0x64a,0x68a,0x68a,0xa,0xa,0x58a,0x5ca,0x348a,0x388a,
+0x454a,0x348a,0x388a,0x35ca,0x34ca,0x354a,0x34ca,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x17,0x17,0x17,0x17,0,0,0,0,0,0,0,0,
+0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,8,8,6,6,6,0x1b,0x1b,0x1b,8,8,8,
+8,8,8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,6,6,6,6,6,
+6,6,6,0x1b,0x1b,6,6,6,6,6,6,6,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,6,6,6,6,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0x1b,0x1b,6,6,6,0x1b,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,
+0,0,0,0,0,0,0,0,0x58b,0x5cb,0x60b,0x64b,0x68b,0x6cb,0x70b,0x74b,
+0x78b,0x7cb,0xa4b,0xccb,0xf4b,0x11cb,0x144b,0x16cb,0x194b,0x1bcb,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,2,2,2,2,2,2,2,0,2,2,
+2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,1,0,1,1,
+0,0,1,0,0,1,1,0,0,1,1,1,1,0,1,1,
+1,1,1,1,1,1,2,2,2,2,0,2,0,2,2,2,
+2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+2,2,2,2,1,1,0,1,1,1,1,0,0,1,1,1,
+1,1,1,1,1,0,1,1,1,1,1,1,1,0,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,1,1,0,1,1,1,1,0,
+1,1,1,1,1,0,1,0,0,0,1,1,1,1,1,1,
+1,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+2,2,2,2,2,2,0,0,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,0x18,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,0x18,2,2,2,2,
+2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,0x18,2,2,2,2,
+2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+2,0x18,2,2,2,2,2,2,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,2,2,2,0x18,2,2,2,2,
+2,2,1,2,0,0,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,
+0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x49,0x89,0xc9,0x109,0x149,0x189,
+0x1c9,0x209,0x249,0x289,0x49,0x89,0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x49,0x89,
+0xc9,0x109,0x149,0x189,0x1c9,0x209,0x249,0x289,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x2cb,0x2cb,0x30b,0x34b,0x38b,0x3cb,0x40b,0x44b,
+0x48b,0x4cb,0x50b,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0x1b,0,0,
+0,0,0,0,0,0,0,0,0,0x1b,0,0x1b,0,0,0x1b,0,
+0,0,0x1b,0,0,0,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,0,0,
+0,0,0,0x1b,0,0,0,0,0,0,0,0x1b,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0x1b,0,0x1b,0x1b,0,0,0x1b,0,0,0,0,
+0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,0,0,0x1b,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x1b,0x1b,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,5,0x705,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0x645,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,0x645,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,0x685,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,0xcc5,5,5,5,5,5,5,5,5,0xf45,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,0xf45,5,5,5,
+5,5,5,5,5,5,5,5,5,5,0x6c5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,0x605,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,0x605,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0x605,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,0x605,5,5,5,5,5,5,5,5,5,5,5,5,
+5,0x645,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0x785,5,5,5,5,5,5,5,5,5,5,5,
+5,5,5,5,0,0x10,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
+0x10,0x10,0x10,0x10,6,6,6,6,6,6,6,6,6,6,6,6,
+6,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,
+0x11,0x11,0,0,0,0,0,0
+};
+
+static const UTrie2 propsTrie={
+    propsTrie_index,
+    propsTrie_index+3692,
+    NULL,
+    3692,
+    12780,
+    0xa40,
+    0xeec,
+    0x0,
+    0x0,
+    0x110000,
+    0x4054,
+    NULL, 0, FALSE, FALSE, 0, NULL
+};
+
+static const uint16_t propsVectorsTrie_index[19848]={
+0x39b,0x3a3,0x3ab,0x3b3,0x3cb,0x3d3,0x3db,0x3e3,0x3eb,0x3f3,0x3fb,0x403,0x40b,0x413,0x41b,0x423,
+0x42a,0x432,0x43a,0x442,0x445,0x44d,0x455,0x45d,0x465,0x46d,0x475,0x47d,0x485,0x48d,0x495,0x49d,
+0x4a5,0x4ad,0x4b4,0x4bc,0x4c4,0x4cc,0x4d4,0x4dc,0x4e4,0x4ec,0x4f1,0x4f9,0x500,0x508,0x510,0x518,
+0x520,0x528,0x530,0x538,0x53f,0x547,0x54f,0x557,0x55f,0x567,0x56f,0x577,0x57f,0x587,0x58f,0x597,
+0x59f,0x5a6,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x5ae,0x5b4,0x5bc,0x5c4,0x5cc,0x5d2,0x5da,0x5e2,
+0x5ea,0x5f0,0x5f8,0x600,0x608,0x60e,0x616,0x61e,0x626,0x62c,0x634,0x63c,0x644,0x64c,0x654,0x65b,
+0x663,0x669,0x671,0x679,0x681,0x687,0x68f,0x697,0x69f,0x6a5,0x6ad,0x6b5,0x6bd,0x6c4,0x6cc,0x6d4,
+0x6dc,0x6e0,0x6e8,0x6ef,0x6f7,0x6ff,0x707,0x70f,0x717,0x71f,0x727,0x72f,0x737,0x73f,0x747,0x74e,
+0x756,0x75e,0x766,0x76e,0x776,0x77e,0x785,0x789,0x791,0x791,0x793,0x79b,0x79c,0x7a4,0x7a6,0x7a8,
+0x7b0,0x7b2,0x7b9,0x7b2,0x7c1,0x7b7,0x7c9,0x7cf,0x7d4,0x7b2,0x7da,0x7e2,0x7ea,0x7f2,0x7f2,0x7f5,
+0x7fd,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,0x7fe,
+0x7fe,0x7fe,0x7fe,0x803,0x80b,0x813,0x813,0x819,0x821,0x829,0x831,0x839,0x841,0x849,0x851,0x859,
+0x861,0x869,0x871,0x873,0x869,0x87b,0x87f,0x882,0x88a,0x892,0x89a,0x89f,0x8a7,0x8ad,0x8b5,0x8bd,
+0x8c5,0x8cd,0x8d0,0x8d8,0x8e0,0x8e8,0x3bb,0x3bb,0x8f0,0x8f5,0x8fd,0x905,0x90d,0x915,0x3bb,0x3bb,
+0x91d,0x924,0x92c,0x933,0x3bb,0x3bb,0x93b,0x943,0x94b,0x952,0x959,0x961,0x969,0x970,0x978,0x97f,
+0x987,0x987,0x987,0x987,0x98a,0x987,0x987,0x992,0x99a,0x9a2,0x9aa,0x9b2,0x9a2,0x9ba,0x9c2,0x9ca,
+0x9d2,0x9da,0x9e2,0x9ea,0x9f2,0x9fa,0xa01,0xa09,0xa11,0xa19,0xa21,0xa29,0xa31,0xa38,0xa3f,0xa47,
+0xa4f,0xa57,0xa5f,0xa67,0xa6f,0xa76,0xa7e,0xa86,0xa8e,0xa96,0xa99,0xa9b,0xaa3,0xaaa,0xab0,0xab8,
+0xac0,0xac7,0xacf,0xad7,0xadc,0xadf,0xae5,0xaeb,0xaf3,0xaf3,0xaf8,0xafc,0xb04,0xb0c,0xb14,0xb1c,
+0xb24,0xb2c,0xb34,0xb3c,0xb44,0xb4c,0xb54,0xb5c,0xb64,0xb6a,0xb72,0xb7a,0xb82,0xb88,0xb90,0xb97,
+0xb9f,0xb9f,0xb9f,0xb9f,0xb9f,0xb9f,0xb9f,0xb9f,0xba7,0xba7,0xba7,0xba7,0xbaf,0xbb6,0xbb8,0xbbf,
+0xbc7,0xbcb,0xbcb,0xbce,0xbcb,0xbcb,0xbd4,0xbcb,0xbdc,0xbe4,0xbeb,0xbf2,0xbf2,0xbf2,0xbf2,0xbf2,
+0xbfa,0xbff,0xc03,0xc0b,0xc13,0xc13,0xc13,0xc1a,0xc22,0xc29,0xc2d,0xc34,0xc3c,0xc44,0xc44,0xc4c,
+0xc54,0xc5c,0xc61,0xc61,0xc69,0xc71,0xc71,0xc75,0xc7d,0xc7d,0xc7d,0xc7d,0xc7d,0xc7d,0xc80,0xc88,
+0xc90,0xc98,0xca0,0xca8,0xcb0,0xcb8,0xcc0,0xcc8,0xcd0,0xcd5,0xcda,0xce1,0xce6,0xcee,0xcf6,0xcfd,
+0xd05,0xd0d,0xd14,0xd1c,0xd24,0xd28,0xd30,0xd34,0xd3c,0xd3c,0xd3e,0xd44,0xd4b,0xd4b,0xd4c,0xd54,
+0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,
+0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,
+0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,
+0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,
+0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,
+0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,
+0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,
+0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,
+0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,
+0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,
+0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,
+0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,
+0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5c,0xd5f,0xd67,0xd67,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,
+0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd6f,0xd76,0xd7d,0xd80,
+0xd88,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,
+0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,0xd8e,
+0xd8e,0xd8e,0xd8e,0xd8e,0xd93,0xd9b,0xda3,0xda7,0xdaf,0xdaf,0xdaf,0xdaf,0xdaf,0xdaf,0xdaf,0xdaf,
+0xdb4,0xdbc,0xdc4,0xdcc,0xdd4,0xddc,0xddc,0xde0,0xde8,0xdf0,0xdf5,0xdf9,0xe01,0xe05,0xe05,0xe07,
+0xe0f,0xe17,0xe1f,0xe22,0xe2a,0xe2d,0xe34,0xe3c,0xe44,0xe4b,0xe52,0xe5a,0xe62,0xe66,0xe6e,0x3bb,
+0xe76,0xe7c,0xe84,0xe8c,0xe94,0xe98,0xea0,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0xea8,0xeb0,
+0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,
+0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,
+0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,
+0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,
+0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,
+0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,
+0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,
+0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,
+0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,
+0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,
+0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,
+0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,
+0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,
+0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,
+0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,
+0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,
+0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,
+0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,
+0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,
+0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,
+0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,
+0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xebe,0xeb8,0xeb9,0xeba,0xebb,0xebc,0xebd,0xec5,0xecc,0xecf,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,
+0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,0xee7,
+0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,
+0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,
+0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,
+0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,
+0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,
+0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,
+0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,
+0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,
+0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,
+0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,
+0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,
+0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,
+0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xeef,0xef7,0xef7,0xef7,0xef7,0xef7,0xef7,0xef7,0xef7,
+0xefc,0xf04,0xf08,0xf0e,0xf12,0xf12,0xf14,0xf1b,0xf23,0xf2b,0xf33,0xf38,0xf3f,0xf47,0xf4c,0xf54,
+0xf5c,0xf5c,0xf5d,0xf65,0xf68,0xf6e,0xf6f,0xf77,0xf7d,0xf82,0xf8a,0xf92,0xf9a,0xfa2,0xfaa,0xfae,
+0xfb6,0xfbe,0xfc6,0xfce,0xfd6,0xfdc,0xfe1,0xfe6,0xfee,0xff6,0xffe,0x1006,0x100b,0x1013,0x101b,0x1023,
+0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,
+0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xed7,0xedf,0xedf,0xedf,0xedf,
+0xeec,0xeec,0xf2c,0xf6c,0xfac,0xfec,0x102c,0x106c,0x10a8,0x10e8,0x1114,0x1154,0x1194,0x11d4,0x1214,0x1254,
+0x1294,0x12d0,0x1310,0x1350,0x1390,0x13c4,0x1400,0x1440,0x1480,0x14c0,0x14fc,0x153c,0x157c,0x15bc,0x15fc,0x163c,
+0xa80,0xac0,0xafc,0xa40,0xb3c,0xa40,0xb7c,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xbbc,0xa40,0xa40,0xa40,0xbfc,0xc14,
+0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,0xc54,
+0xc54,0xc54,0xc54,0xc54,0xc5e,0xc96,0xc9d,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xd17,
+0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,
+0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xcd7,0xd57,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xc14,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xc14,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xc14,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xc14,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xc14,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xc14,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xc14,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xc14,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xc14,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xc14,
+0xd97,0xda7,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,
+0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xa40,0xc14,
+0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,
+0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde7,0xde8,
+0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,
+0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe28,0xe29,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x102b,0x1032,0x103a,0x1042,0x104a,0x104a,0x104a,0x104c,0x1054,0x1057,0x105f,0x1062,0x1068,0x106f,0x1073,0x1077,
+0x3bb,0x3bb,0x3bb,0x3bb,0x107f,0x1087,0x108b,0x3bb,0x1093,0x109b,0x10a1,0x3bb,0x10a9,0x10b1,0x10b8,0x3bb,
+0x10c0,0x10c7,0x10cc,0x10d0,0x10d8,0x10e0,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x10e8,0x10eb,0x10f3,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x10fb,0x1103,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x110b,0x1112,0x111a,0x1122,0x3bb,0x3bb,0x3bb,0x3bb,0x112a,0x112d,0x1135,0x113d,0x3bb,0x3bb,0x3bb,0x3bb,
+0x1145,0x1145,0x114b,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x1153,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x115b,0x1163,0x116b,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x1173,0x1173,0x1173,0x1173,
+0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,
+0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1173,0x1178,0x117c,0x117c,0x117c,0x117c,0x1184,0x1184,0x1184,0x118c,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x1194,0x1194,0x1194,0x1194,
+0x1194,0x1194,0x1194,0x1194,0x1194,0x1194,0x1194,0x1194,0x1194,0x1194,0x1194,0x1194,0x1194,0x1194,0x1196,0x1194,
+0x119e,0x1194,0x1194,0x1194,0x1194,0x1194,0x1194,0x11a1,0x1194,0x1194,0x1194,0x1194,0x1194,0x11a8,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x11b0,0x11b0,0x11b0,0x11b0,
+0x11b0,0x11b0,0x11b0,0x11b3,0x11bb,0x11c2,0x11c5,0x11cd,0x11d5,0x11db,0x11e3,0x11eb,0x11f3,0x11f3,0x11fb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x1203,0x1203,0x1206,0x120e,0x3bb,0x3bb,0x3bb,0x3bb,0x1216,0x121d,0x1222,0x1228,
+0x1230,0x1238,0x1240,0x121a,0x1248,0x1250,0x1258,0x125d,0x122f,0x1216,0x121d,0x1219,0x1228,0x1265,0x1217,0x1268,
+0x121a,0x1270,0x1278,0x1280,0x1287,0x1273,0x127b,0x1283,0x128a,0x1276,0x1292,0x1296,0x129e,0x12a3,0x12a7,0x12a7,
+0x12aa,0x3bb,0x3bb,0x3bb,0x12b2,0x12b8,0x12c0,0x12c8,0x12d0,0x12d5,0x12d5,0x12d5,0x12dd,0x12e1,0x12e9,0x12ec,
+0x12ec,0x12ec,0x12ec,0x12ec,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,0x3bb,
+0x3bb,0x3bb,0x3bb,0x12f4,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,
+0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,
+0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,
+0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,0x12fc,
+0x12fc,0x12fc,0x12fc,0x12fc,0x12ff,0x1307,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,
+0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,
+0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,
+0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,
+0x130f,0x130f,0x130f,0x130f,0x130f,0x130f,0x1312,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,
+0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,
+0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,
+0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,
+0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x131a,0x131a,0x131a,0x131a,0x131a,0x131a,0x131a,0x131a,0x131a,
+0x131a,0x131a,0x131a,0x131a,0x131a,0x131a,0x131a,0x131b,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,
+0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,
+0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,
+0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1323,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,
+0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,
+0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,
+0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,
+0x1307,0x1307,0x1307,0x1307,0x1307,0x1307,0x1323,0x132b,0x1333,0x1333,0x1333,0x133b,0x133b,0x133b,0x133b,0x1343,
+0x1343,0x1343,0x1343,0x1343,0x1343,0x1343,0x1347,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,
+0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,
+0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,
+0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,
+0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x133b,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,
+0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,
+0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,
+0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,
+0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x134f,0x1350,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,
+0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,
+0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,
+0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,
+0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1358,0x1359,0x39a,0x39a,0x39a,0x1bc,0x1bc,0x1bc,0x1bc,
+0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x1bf,0x1c8,0x1c2,0x1c2,0x1c5,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,
+0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x1bc,0x6f6,0x6f0,0x6d2,0x6ba,
+0x6c6,0x6c3,0x6ba,0x6d5,0x6c0,0x6cc,0x6ba,0x6e7,0x6de,0x6cf,0x6f3,0x6c9,0x6b7,0x6b7,0x6b7,0x6b7,
+0x6b7,0x6b7,0x6b7,0x6b7,0x6b7,0x6b7,0x6db,0x6d8,0x6e1,0x6e1,0x6e1,0x6f0,0x6ba,0x702,0x702,0x702,
+0x702,0x702,0x702,0x6fc,0x6fc,0x6fc,0x6fc,0x6fc,0x6fc,0x6fc,0x6fc,0x6fc,0x6fc,0x6fc,0x6fc,0x6fc,
+0x6fc,0x6fc,0x6fc,0x6fc,0x6fc,0x6fc,0x6fc,0x6c0,0x6c6,0x6cc,0x6ed,0x6b4,0x6ea,0x6ff,0x6ff,0x6ff,
+0x6ff,0x6ff,0x6ff,0x6f9,0x6f9,0x6f9,0x6f9,0x6f9,0x6f9,0x6f9,0x6f9,0x6f9,0x6f9,0x6f9,0x6f9,0x6f9,
+0x6f9,0x6f9,0x6f9,0x6f9,0x6f9,0x6f9,0x6f9,0x6c0,0x6e4,0x6bd,0x6e1,0x1bc,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x1cb,0x1cb,0x1cb,0x1cb,
+0x1cb,0x1da,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,
+0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1cb,0x1ce,0x552,0x70b,0x70e,
+0x558,0x70e,0x708,0x54c,0x543,0x1d4,0x561,0x1d7,0x711,0x53a,0x54f,0x705,0x555,0x55e,0x540,0x540,
+0x546,0x1d1,0x54c,0x549,0x543,0x540,0x561,0x1d7,0x53d,0x53d,0x53d,0x552,0x1e0,0x1e0,0x1e0,0x1e0,
+0x1e0,0x1e0,0x56a,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x56a,0x1e0,0x1e0,0x1e0,
+0x1e0,0x1e0,0x1e0,0x55b,0x56a,0x1e0,0x1e0,0x1e0,0x1e0,0x1e0,0x56a,0x564,0x567,0x567,0x1dd,0x1dd,
+0x1dd,0x1dd,0x564,0x1dd,0x567,0x567,0x567,0x1dd,0x567,0x567,0x1dd,0x1dd,0x564,0x1dd,0x567,0x567,
+0x1dd,0x1dd,0x1dd,0x55b,0x564,0x567,0x567,0x1dd,0x567,0x1dd,0x564,0x1dd,0x1ec,0x570,0x1ec,0x1e3,
+0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,0x1e9,0x56d,0x1ec,0x570,
+0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x570,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,
+0x1ec,0x1e3,0x576,0x56d,0x1ec,0x1e3,0x1ec,0x570,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x56d,0x579,0x573,
+0x1ec,0x1e3,0x1ec,0x1e3,0x56d,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,0x579,0x573,0x576,0x56d,0x1ec,
+0x570,0x1ec,0x1e3,0x1ec,0x570,0x57c,0x576,0x56d,0x1ec,0x570,0x1ec,0x1e3,0x1ec,0x1e3,0x576,0x56d,
+0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,
+0x1ec,0x1e3,0x576,0x56d,0x1ec,0x1e3,0x1ec,0x570,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,
+0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1ec,0x1e3,0x1ec,0x1e3,0x1ec,0x1e3,0x1e6,0x1ef,0x1fb,0x1fb,0x1ef,
+0x1fb,0x1ef,0x1fb,0x1fb,0x1ef,0x1fb,0x1fb,0x1fb,0x1ef,0x1ef,0x1fb,0x1fb,0x1fb,0x1fb,0x1ef,0x1fb,
+0x1fb,0x1ef,0x1fb,0x1fb,0x1fb,0x1ef,0x1ef,0x1ef,0x1fb,0x1fb,0x1ef,0x1fb,0x1fe,0x1f2,0x1fb,0x1ef,
+0x1fb,0x1ef,0x1fb,0x1fb,0x1ef,0x1fb,0x1ef,0x1ef,0x1fb,0x1ef,0x1fb,0x1fe,0x1f2,0x1fb,0x1fb,0x1fb,
+0x1ef,0x1fb,0x1ef,0x1fb,0x1fb,0x1ef,0x1ef,0x1f8,0x1fb,0x1ef,0x1ef,0x1ef,0x1f8,0x1f8,0x1f8,0x1f8,
+0x201,0x201,0x1f5,0x201,0x201,0x1f5,0x201,0x201,0x1f5,0x1fe,0x57f,0x1fe,0x57f,0x1fe,0x57f,0x1fe,
+0x57f,0x1fe,0x57f,0x1fe,0x57f,0x1fe,0x57f,0x1fe,0x57f,0x1ef,0x1fe,0x1f2,0x1fe,0x1f2,0x1fe,0x1f2,
+0x1fb,0x1ef,0x1fe,0x1f2,0x1fe,0x1f2,0x1fe,0x1f2,0x1fe,0x1f2,0x1fe,0x1f2,0x1f2,0x201,0x201,0x1f5,
+0x1fe,0x1f2,0x861,0x861,0x864,0x85e,0x1fe,0x1f2,0x1fe,0x1f2,0x1fe,0x1f2,0x1fe,0x1f2,0x1fe,0x1f2,
+0x1fe,0x1f2,0x1fe,0x1f2,0x1fe,0x1f2,0x1fe,0x1f2,0x1fe,0x1f2,0x1fe,0x1f2,0x1fe,0x1f2,0x1fe,0x1f2,
+0x864,0x85e,0x864,0x85e,0x861,0x85b,0x864,0x85e,0xa0e,0xb04,0x861,0x85b,0x861,0x85b,0x864,0x85e,
+0x864,0x85e,0x864,0x85e,0x864,0x85e,0x864,0x85e,0x864,0x85e,0x864,0x85e,0xb04,0xb04,0xb04,0xbf1,
+0xbf1,0xbf1,0xbf4,0xbf4,0xbf1,0xbf4,0xbf4,0xbf1,0xbf1,0xbf4,0xd23,0xd26,0xd26,0xd26,0xd26,0xd23,
+0xd26,0xd23,0xd26,0xd23,0xd26,0xd23,0xd26,0xd23,0x204,0x582,0x204,0x204,0x204,0x204,0x204,0x204,
+0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x582,0x204,0x204,0x204,0x204,0x204,0x204,
+0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,
+0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x207,0x204,0x204,0x204,0x204,0x204,0x204,0x204,
+0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x204,0x867,0x867,0x867,
+0x867,0x867,0xb07,0xb07,0x21c,0x21c,0x21c,0x21c,0x21c,0x21c,0x21c,0x21c,0x21c,0x213,0x213,0x213,
+0x213,0x213,0x213,0x213,0x210,0x210,0x20a,0x20a,0x588,0x20a,0x213,0x58b,0x216,0x58b,0x58b,0x58b,
+0x216,0x58b,0x213,0x213,0x58e,0x219,0x20a,0x20a,0x20a,0x20a,0x20a,0x20a,0x585,0x585,0x585,0x585,
+0x20d,0x585,0x20a,0x999,0x21c,0x21c,0x21c,0x21c,0x21c,0x20a,0x20a,0x20a,0x20a,0x20a,0x86a,0x86a,
+0x86d,0x86a,0x86d,0xb0a,0xb0a,0xb0a,0xb0a,0xb0a,0xb0a,0xb0a,0xb0a,0xb0a,0xb0a,0xb0a,0xb0a,0xb0a,
+0xb0a,0xb0a,0xb0a,0xb0a,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,
+0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,
+0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,
+0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,0x591,
+0x591,0x591,0x591,0x591,0x594,0x594,0x591,0x594,0x594,0x59a,0x99c,0x99c,0x99c,0x99c,0x99c,0x99c,
+0x99c,0x99c,0x99c,0xac5,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xbd0,0xcf6,0xcf6,0xcf6,0xcf6,
+0xcf9,0xbd3,0xbd3,0xbd3,0x597,0x597,0x99f,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,0xac2,
+0xac2,0xac2,0xac2,0xac2,0xdd1,0xdce,0xdd1,0xdce,0x228,0x231,0xdd1,0xdce,6,6,0x237,0xd29,
+0xd29,0xd29,0x21f,6,6,6,6,6,0x234,0x222,0x246,0x225,0x246,0x246,0x246,6,
+0x246,6,0x246,0x246,0x23d,0x5a0,0x5a0,0x5a0,0x5a0,0x5a0,0x5a0,0x5a0,0x5a0,0x5a0,0x5a0,0x5a0,
+0x5a0,0x5a0,0x5a0,0x5a0,0x5a0,0x5a0,6,0x5a0,0x5a0,0x5a0,0x5a0,0x5a0,0x5a0,0x5a0,0x246,0x246,
+0x23d,0x23d,0x23d,0x23d,0x23d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,
+0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x23a,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x59d,0x23d,0x23d,
+0x23d,0x23d,0x23d,0xdd1,0x249,0x249,0x24c,0x246,0x246,0x249,0x240,0x870,0xa17,0xa14,0x243,0x870,
+0x243,0x870,0x243,0x870,0x243,0x870,0x22e,0x22b,0x22e,0x22b,0x22e,0x22b,0x22e,0x22b,0x22e,0x22b,
+0x22e,0x22b,0x22e,0x22b,0x249,0x249,0x240,0x23a,0x9c9,0x9c6,0xa11,0xb10,0xb0d,0xb13,0xb10,0xb0d,
+0xbf7,0xbfa,0xbfa,0xbfa,0x87f,0x5ac,0x25e,0x261,0x25e,0x25e,0x25e,0x261,0x25e,0x25e,0x25e,0x25e,
+0x261,0x87f,0x261,0x25e,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5ac,0x5a9,0x5a9,
+0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,0x5a9,
+0x5a9,0x5a9,0x5a9,0x5a9,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a6,0x5a3,0x5a3,
+0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,0x5a3,
+0x879,0x5a6,0x258,0x25b,0x258,0x258,0x258,0x25b,0x258,0x258,0x258,0x258,0x25b,0x879,0x25b,0x258,
+0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,
+0x25e,0x258,0x25e,0x258,0x25e,0x258,0x261,0x25b,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,
+0x25e,0x258,0x255,0x252,0x252,0x24f,0x24f,0xdd4,0x873,0x873,0xa1d,0xa1a,0x87c,0x876,0x87c,0x876,
+0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,
+0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,
+0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,0x25e,0x258,
+0x25e,0x261,0x25b,0x25e,0x258,0xa1d,0xa1a,0x25e,0x258,0xa1d,0xa1a,0x25e,0x258,0xa1d,0xa1a,0xd2c,
+0x261,0x25b,0x261,0x25b,0x25e,0x258,0x261,0x25b,0x25e,0x258,0x261,0x25b,0x261,0x25b,0x261,0x25b,
+0x25e,0x258,0x261,0x25b,0x261,0x25b,0x261,0x25b,0x25e,0x258,0x261,0x25b,0x87f,0x879,0x261,0x25b,
+0x261,0x25b,0x261,0x25b,0x261,0x25b,0xc00,0xbfd,0x261,0x25b,0xd2f,0xd2c,0xd2f,0xd2c,0xd2f,0xd2c,
+0xa83,0xa80,0xa83,0xa80,0xa83,0xa80,0xa83,0xa80,0xa83,0xa80,0xa83,0xa80,0xa83,0xa80,0xa83,0xa80,
+0xd5c,0xd59,0xd5c,0xd59,0xe4f,0xe4c,0xe4f,0xe4c,0xe4f,0xe4c,0xe4f,0xe4c,0xe4f,0xe4c,0xe4f,0xe4c,
+0xe4f,0xe4c,0xe4f,0xe4c,0xfa2,0xf9f,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,0xbd,
+9,0x273,0x273,0x273,0x273,0x273,0x273,0x273,0x273,0x273,0x273,0x273,0x273,0x273,0x273,0x273,
+0x273,0x273,0x273,0x273,0x273,0x273,0x273,0x273,0x273,0x273,0x273,9,9,0x276,0x267,0x267,
+0x279,0x26a,0x279,0x267,9,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,
+0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,
+0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x26d,0x270,9,0x264,0x882,9,9,9,9,9,
+0xc,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,
+0x7f5,0x7f5,0xc03,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,0x7f5,
+0x27c,0x27c,0x27c,0x27c,0x27c,0x27c,0x27c,0x27c,0x27c,0x27c,0xd32,0x27c,0x27c,0x27c,0x288,0x27c,
+0x27f,0x27c,0x27c,0x28b,0x7f8,0xc06,0xc09,0xc06,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0xc,
+0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,
+0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0x28e,0xc,0xc,0xc,0xc,0xc,
+0x28e,0x28e,0x28e,0x285,0x282,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0xc,0xc,
+0xb16,0xb16,0xb16,0xb16,0xf,0xf,0xddd,0xddd,0xddd,0xdda,0xdda,0xc12,0x297,0xb25,0xb22,0xb22,
+0xb19,0xb19,0xb19,0xb19,0xb19,0xb19,0xdd7,0xdd7,0xdd7,0xdd7,0xdd7,0x294,0xf,0xf,0xc0f,0x2a0,
+0xf,0x2c1,0x2c4,0x2c4,0x2c4,0x2c4,0x2c4,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,
+0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0xde0,0xde0,0xde0,0xde0,0xde0,
+0x29d,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2a6,0x2a6,0x2a6,0x2a6,0x2a6,
+0x2a6,0x2a6,0x2a6,0x885,0x885,0x885,0xb19,0xb1f,0xb1c,0xc0c,0xc0c,0xc0c,0xc0c,0xc0c,0xc0c,0xf,
+0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x29a,0x2bb,0x2b8,0x2b5,0x2b2,0xa20,0xa20,
+0x2a3,0x2c1,0x2c1,0x2c1,0x2c1,0x2c7,0x2c7,0x2c7,0x2c7,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,
+0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,
+0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,
+0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,
+0x2c1,0x2c1,0x2c1,0x2c1,0x88b,0x88b,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x88b,0x2c4,0x2c1,0x2c4,0x2c1,
+0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x2c1,0x88b,0x2c1,0x2c1,0x2c1,0x2c4,
+0x2cd,0x2c1,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x2ac,0x291,0x2a9,0x2af,0x2af,0x2ac,0x2ac,0x2ac,
+0x2ac,0x2ca,0x2ca,0x2ac,0x2ac,0x2b2,0x2af,0x2af,0x2af,0x2ac,0xb28,0xb28,0x2be,0x2be,0x2be,0x2be,
+0x2be,0x2be,0x2be,0x2be,0x2be,0x2be,0x88b,0x88b,0x88b,0x888,0x888,0xb28,0x8a3,0x8a3,0x8a3,0x89d,
+0x89d,0x89d,0x89d,0x89d,0x89d,0x89d,0x89d,0x89a,0x89d,0x89a,0x12,0x88e,0x8a0,0x891,0x8a0,0x8a0,
+0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,
+0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0x8a0,0xb2b,0xb2b,0xb2b,0x897,0x897,0x897,0x897,
+0x897,0x897,0x897,0x897,0x897,0x897,0x897,0x897,0x897,0x897,0x897,0x897,0x894,0x894,0x894,0x894,
+0x894,0x894,0x894,0x894,0x894,0x894,0x894,0x12,0x12,0xb2b,0xb2b,0xb2b,0xc6f,0xc6f,0xc6f,0xc6f,
+0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,
+0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xc6f,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,
+0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0xe61,0x8a9,0x8a9,0x8a9,0x8a9,
+0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,
+0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,0x8a9,
+0x8a9,0x8a9,0x8a6,0x8a6,0x8a6,0x8a6,0x8a6,0x8a6,0x8a6,0x8a6,0x8a6,0x8a6,0x8a6,0xa23,0x15,0x15,
+0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,0xd74,0xd74,0xd74,0xd74,
+0xd74,0xd74,0xd74,0xd74,0xd74,0xd74,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,
+0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,
+0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd77,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,0xd6b,
+0xd7a,0xd7a,0xd6e,0xd6e,0xd71,0xd80,0xd7d,0x120,0x120,0x120,0x120,0x120,0xfcc,0xfcc,0xfcc,0xfcc,
+0xfcc,0xfcc,0xfcc,0xfcc,0xfcc,0xfcc,0xfcc,0xfcc,0xfcc,0xfcc,0xfcc,0xfcc,0xfcc,0xfcc,0xfcc,0xfcc,
+0xfcc,0xfcc,0xfc3,0xfc3,0xfc6,0xfc6,0xfcc,0xfc3,0xfc3,0xfc3,0xfc3,0xfc3,0xfcc,0xfc3,0xfc3,0xfc3,
+0xfcc,0xfc3,0xfc3,0xfc3,0xfc3,0xfc0,0x162,0x162,0xfc9,0xfc9,0xfc9,0xfc9,0xfc9,0xfc9,0xfc9,0xfc9,
+0xfc9,0xfc9,0xfc9,0xfc9,0xfc9,0xfc9,0xfc9,0x162,0xf72,0x2d9,0x2d9,0x2e5,0xb2e,0x2e8,0x2e8,0x2e8,
+0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,
+0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2eb,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,
+0x2e8,0x2eb,0x2e8,0x2e8,0x2eb,0x2e8,0x2e8,0x2e8,0x2e8,0x2e8,0x18,0x18,0x2dc,0x2e8,0x2e5,0x2e5,
+0x2e5,0x2d9,0x2d9,0x2d9,0x2d9,0x2d9,0x2d9,0x2d9,0x2d9,0x2e5,0x2e5,0x2e5,0x2e5,0x2df,0xf75,0x18,
+0x2e8,0x2d6,0x2d6,0x2dc,0x2dc,0xf72,0x18,0x18,0x2eb,0x2eb,0x2eb,0x2eb,0x2eb,0x2eb,0x2eb,0x2eb,
+0x2e8,0x2e8,0x2d9,0x2d9,0x2d3,0x2d3,0x2e2,0x2e2,0x2e2,0x2e2,0x2e2,0x2e2,0x2e2,0x2e2,0x2e2,0x2e2,
+0x2d0,0xde6,0xde3,0x18,0x18,0x18,0x18,0x18,0x18,0xf78,0xf78,0xd35,0xd35,0xc15,0xd35,0xd35,
+0x1b,0x2ee,0x300,0x300,0x1b,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x1b,0x1b,0x306,
+0x306,0x1b,0x1b,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x306,
+0x306,0x1b,0x306,0x306,0x306,0x306,0x306,0x306,0x306,0x1b,0x306,0x1b,0x1b,0x1b,0x306,0x306,
+0x306,0x306,0x1b,0x1b,0x2f1,0xb31,0x2ee,0x300,0x300,0x2ee,0x2ee,0x2ee,0x2ee,0x1b,0x1b,0x300,
+0x300,0x1b,0x1b,0x303,0x303,0x2f4,0xc18,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x1b,0x2ee,
+0x1b,0x1b,0x1b,0x1b,0x309,0x309,0x1b,0x309,0x306,0x306,0x2ee,0x2ee,0x1b,0x1b,0x2fd,0x2fd,
+0x2fd,0x2fd,0x2fd,0x2fd,0x2fd,0x2fd,0x2fd,0x2fd,0x306,0x306,0x2fa,0x2fa,0x2f7,0x2f7,0x2f7,0x2f7,
+0x2f7,0x2fa,0x2f7,0xf7b,0x1b,0x1b,0x1b,0x1b,0x1e,0xb34,0x30c,0xb37,0x1e,0x31b,0x31b,0x31b,
+0x31b,0x31b,0x31b,0x1e,0x1e,0x1e,0x1e,0x31b,0x31b,0x1e,0x1e,0x31b,0x31b,0x31b,0x31b,0x31b,
+0x31b,0x31b,0x31b,0x31b,0x31b,0x31b,0x31b,0x31b,0x31b,0x1e,0x31b,0x31b,0x31b,0x31b,0x31b,0x31b,
+0x31b,0x1e,0x31b,0x31e,0x1e,0x31b,0x31e,0x1e,0x31b,0x31b,0x1e,0x1e,0x30f,0x1e,0x318,0x318,
+0x318,0x30c,0x30c,0x1e,0x1e,0x1e,0x1e,0x30c,0x30c,0x1e,0x1e,0x30c,0x30c,0x312,0x1e,0x1e,
+0x1e,0xde9,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x31e,0x31e,0x31e,0x31b,0x1e,0x31e,0x1e,
+0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x315,0x315,0x315,0x315,0x315,0x315,0x315,0x315,0x315,0x315,
+0x30c,0x30c,0x31b,0x31b,0x31b,0xde9,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
+0x21,0x321,0x321,0x32d,0x21,0x330,0x330,0x330,0x330,0x330,0x330,0x330,0xb40,0x330,0x21,0x330,
+0x330,0x330,0x21,0x330,0x330,0x330,0x330,0x330,0x330,0x330,0x330,0x330,0x330,0x330,0x330,0x330,
+0x330,0x21,0x330,0x330,0x330,0x330,0x330,0x330,0x330,0x21,0x330,0x330,0x21,0x330,0x330,0x330,
+0x330,0x330,0x21,0x21,0x324,0x330,0x32d,0x32d,0x32d,0x321,0x321,0x321,0x321,0x321,0x21,0x321,
+0x321,0x32d,0x21,0x32d,0x32d,0x327,0x21,0x21,0x330,0x21,0x21,0x21,0x21,0x21,0x21,0x21,
+0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x330,0xb40,0xb3a,0xb3a,0x21,0x21,0x32a,0x32a,
+0x32a,0x32a,0x32a,0x32a,0x32a,0x32a,0x32a,0x32a,0x21,0xb3d,0x21,0x21,0x21,0x21,0x21,0x21,
+0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x24,0x333,0x342,0x342,0x24,0x348,0x348,0x348,
+0x348,0x348,0x348,0x348,0x348,0x24,0x24,0x348,0x348,0x24,0x24,0x348,0x348,0x348,0x348,0x348,
+0x348,0x348,0x348,0x348,0x348,0x348,0x348,0x348,0x348,0x24,0x348,0x348,0x348,0x348,0x348,0x348,
+0x348,0x24,0x348,0x348,0x24,0xb43,0x348,0x348,0x348,0x348,0x24,0x24,0x336,0x348,0x333,0x333,
+0x342,0x333,0x333,0x333,0xdec,0x24,0x24,0x342,0x345,0x24,0x24,0x345,0x345,0x339,0x24,0x24,
+0x24,0x24,0x24,0x24,0x24,0x24,0x333,0x333,0x24,0x24,0x24,0x24,0x34b,0x34b,0x24,0x348,
+0x348,0x348,0xdec,0xdec,0x24,0x24,0x33f,0x33f,0x33f,0x33f,0x33f,0x33f,0x33f,0x33f,0x33f,0x33f,
+0x33c,0xb43,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+0x27,0x27,0x34e,0x360,0x27,0x360,0x360,0x360,0x360,0x360,0x360,0x27,0x27,0x27,0x360,0x360,
+0x360,0x27,0x360,0x360,0x363,0x360,0x27,0x27,0x27,0x360,0x360,0x27,0x360,0x27,0x360,0x360,
+0x27,0x27,0x27,0x360,0x360,0x27,0x27,0x27,0x360,0x360,0x360,0x27,0x27,0x27,0x360,0x360,
+0x360,0x360,0x360,0x360,0x360,0x360,0xc1e,0x360,0x360,0x360,0x27,0x27,0x27,0x27,0x34e,0x35a,
+0x34e,0x35a,0x35a,0x27,0x27,0x27,0x35a,0x35a,0x35a,0x27,0x35d,0x35d,0x35d,0x351,0x27,0x27,
+0xdef,0x27,0x27,0x27,0x27,0x27,0x27,0x34e,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,
+0x27,0x27,0xc1b,0x357,0x357,0x357,0x357,0x357,0x357,0x357,0x357,0x357,0x354,0x354,0x354,0xb46,
+0xb46,0xb46,0xb46,0xb46,0xb46,0xb49,0xb46,0x27,0x27,0x27,0x27,0x27,0x2a,0x372,0x372,0x372,
+0x2a,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x2a,0x375,0x375,0x375,0x2a,0x375,0x375,
+0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x2a,0x375,0x375,
+0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x375,0x2a,0x375,0x375,0x375,0x375,0x375,0x2a,0x2a,
+0x2a,0xdf8,0x366,0x366,0x366,0x372,0x372,0x372,0x372,0x2a,0x366,0x366,0x369,0x2a,0x366,0x366,
+0x366,0x36c,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x366,0x366,0x2a,0xdf8,0xdf8,0x2a,0x2a,
+0x2a,0x2a,0x2a,0x2a,0x375,0x375,0xdf2,0xdf2,0x2a,0x2a,0x36f,0x36f,0x36f,0x36f,0x36f,0x36f,
+0x36f,0x36f,0x36f,0x36f,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0xdf5,0xdf5,0xdf5,0xdf5,
+0xdf5,0xdf5,0xdf5,0xdf5,0x2d,0x2d,0x381,0x381,0x2d,0x387,0x387,0x387,0x387,0x387,0x387,0x387,
+0x387,0x2d,0x387,0x387,0x387,0x2d,0x387,0x387,0x387,0x387,0x387,0x387,0x387,0x387,0x387,0x387,
+0x387,0x387,0x387,0x387,0x387,0x2d,0x387,0x387,0x387,0x387,0x387,0x387,0x387,0x387,0x387,0x387,
+0x2d,0x387,0x387,0x387,0x387,0x387,0x2d,0x2d,0xb4c,0xb4f,0x381,0x378,0x384,0x381,0x378,0x381,
+0x381,0x2d,0x378,0x384,0x384,0x2d,0x384,0x384,0x378,0x37b,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,
+0x2d,0x378,0x378,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x387,0x2d,0x387,0x387,0xd3b,0xd3b,
+0x2d,0x2d,0x37e,0x37e,0x37e,0x37e,0x37e,0x37e,0x37e,0x37e,0x37e,0x37e,0x2d,0xd38,0xd38,0x2d,
+0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x30,0x30,0x393,0x393,
+0x30,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x30,0x399,0x399,0x399,0x30,0x399,0x399,
+0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x30,0x399,0x399,
+0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x399,0x30,0x30,
+0x30,0xe04,0x38a,0x393,0x393,0x38a,0x38a,0x38a,0xdfb,0x30,0x393,0x393,0x393,0x30,0x396,0x396,
+0x396,0x38d,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38a,0x30,0x30,0x30,0x30,
+0x30,0x30,0x30,0x30,0x399,0x399,0xdfb,0xdfb,0x30,0x30,0x390,0x390,0x390,0x390,0x390,0x390,
+0x390,0x390,0x390,0x390,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0xdfe,0x30,0x30,0x30,0xe01,0xe04,0xe04,
+0xe04,0xe04,0xe04,0xe04,0x33,0x33,0x8b5,0x8b5,0x33,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,
+0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x33,0x33,0x33,0x8bb,0x8bb,
+0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,
+0x8bb,0x8bb,0x33,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x33,0x8bb,0x33,0x33,
+0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x8bb,0x33,0x33,0x33,0x8af,0x33,0x33,0x33,0x33,0x8ac,
+0x8b5,0x8b5,0x8ac,0x8ac,0x8ac,0x33,0x8ac,0x33,0x8b5,0x8b5,0x8b8,0x8b5,0x8b8,0x8b8,0x8b8,0x8ac,
+0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+0x33,0x33,0x8b5,0x8b5,0x8b2,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,
+0x36,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,
+0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,0x3b4,
+0x3b7,0x39f,0x3b7,0x3b1,0x39f,0x39f,0x39f,0x39f,0x39f,0x39f,0x3a5,0x36,0x36,0x36,0x36,0x39c,
+0x3bd,0x3bd,0x3bd,0x3bd,0x3bd,0x3b7,0x3ba,0x3a2,0x3a2,0x3a2,0x3a2,0x3a2,0x3a2,0x39f,0x3a2,0x3a8,
+0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ae,0x3ab,0x3ab,0x36,0x36,0x36,0x36,
+0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x39,0x3cc,0x3cc,0x39,
+0x3cc,0x39,0x39,0x3cc,0x3cc,0x39,0x3cc,0x39,0x39,0x3cc,0x39,0x39,0x39,0x39,0x39,0x39,
+0x3cc,0x3cc,0x3cc,0x3cc,0x39,0x3cc,0x3cc,0x3cc,0x3cc,0x3cc,0x3cc,0x3cc,0x39,0x3cc,0x3cc,0x3cc,
+0x39,0x3cc,0x39,0x3cc,0x39,0x39,0x3cc,0x3cc,0x39,0x3cc,0x3cc,0x3cc,0x3d2,0x3c0,0x3d2,0x3c9,
+0x3c0,0x3c0,0x3c0,0x3c0,0x3c0,0x3c0,0x39,0x3c0,0x3c0,0x3cc,0x39,0x39,0x3d8,0x3d8,0x3d8,0x3d8,
+0x3d8,0x39,0x3d5,0x39,0x3c3,0x3c3,0x3c3,0x3c3,0x3c3,0x3c0,0x39,0x39,0x3c6,0x3c6,0x3c6,0x3c6,
+0x3c6,0x3c6,0x3c6,0x3c6,0x3c6,0x3c6,0x39,0x39,0x3cf,0x3cf,0x39,0x39,0x39,0x39,0x39,0x39,
+0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,
+0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x82e,0x810,0x810,0x810,
+0x810,0x80a,0x810,0x810,0x822,0x810,0x810,0x80d,0x819,0x81f,0x81f,0x81f,0x81f,0x81f,0x822,0x80a,
+0x816,0x80a,0x80a,0x80a,0x801,0x801,0x80a,0x80a,0x80a,0x80a,0x80a,0x80a,0x825,0x825,0x825,0x825,
+0x825,0x825,0x825,0x825,0x825,0x825,0x80a,0x80a,0x80a,0x80a,0x80a,0x80a,0x80a,0x80a,0x80a,0x80a,
+0x80d,0x801,0x80a,0x801,0x80a,0x801,0x81c,0x813,0x81c,0x813,0x82b,0x82b,0x82e,0x82e,0x82e,0x831,
+0x82e,0x82e,0x82e,0x82e,0x3c,0x82e,0x82e,0x82e,0x82e,0x831,0x82e,0x82e,0x82e,0x82e,0x831,0x82e,
+0x82e,0x82e,0x82e,0x831,0x82e,0x82e,0x82e,0x82e,0x831,0x82e,0x82e,0x82e,0x82e,0x82e,0x82e,0x82e,
+0x82e,0x82e,0x82e,0x82e,0x82e,0x831,0x8ca,0xe10,0xe10,0x3c,0x3c,0x3c,0x3c,0x7fb,0x7fb,0x7fe,
+0x7fb,0x7fe,0x7fe,0x807,0x7fe,0x807,0x7fb,0x7fb,0x7fb,0x7fb,0x7fb,0x828,0x7fb,0x7fe,0x801,0x801,
+0x804,0x80d,0x801,0x801,0x82e,0x82e,0x82e,0x82e,0x3c,0x3c,0x3c,0x3c,0x7fb,0x7fb,0x7fb,0x7fe,
+0x7fb,0x7fb,0x8be,0x7fb,0x3c,0x7fb,0x7fb,0x7fb,0x7fb,0x7fe,0x7fb,0x7fb,0x7fb,0x7fb,0x7fe,0x7fb,
+0x7fb,0x7fb,0x7fb,0x7fe,0x7fb,0x7fb,0x7fb,0x7fb,0x7fe,0x7fb,0x8be,0x8be,0x8be,0x7fb,0x7fb,0x7fb,
+0x7fb,0x7fb,0x7fb,0x7fb,0x8be,0x7fe,0x8be,0x8be,0x8be,0x3c,0x8c7,0x8c7,0x8c4,0x8c4,0x8c4,0x8c4,
+0x8c4,0x8c4,0x8c1,0x8c4,0x8c4,0x8c4,0x8c4,0x8c4,0x8c4,0x3c,0xe07,0x8c4,0xc21,0xc21,0xe0a,0xe0d,
+0xe07,0xf7e,0xf7e,0xf7e,0xf7e,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,
+0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,
+0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,
+0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,
+0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0xe2b,0x8df,0x8df,0x8df,0x8e2,0x8df,
+0xe2b,0x8df,0x8df,0xe25,0x8dc,0x8cd,0x8cd,0x8cd,0x8cd,0x8dc,0x8cd,0xe13,0xe13,0xe13,0x8cd,0x8d0,
+0x8dc,0x8d3,0xe19,0xe25,0xe25,0xe13,0xe13,0xe2b,0x8d9,0x8d9,0x8d9,0x8d9,0x8d9,0x8d9,0x8d9,0x8d9,
+0x8d9,0x8d9,0x8e5,0x8e5,0x8d6,0x8d6,0x8d6,0x8d6,0x8df,0x8df,0x8df,0x8df,0x8df,0x8df,0x8dc,0x8dc,
+0x8cd,0x8cd,0xe2b,0xe2b,0xe2b,0xe2b,0xe13,0xe13,0xe13,0xe2b,0xe25,0xe22,0xe22,0xe2b,0xe2b,0xe25,
+0xe25,0xe22,0xe22,0xe22,0xe22,0xe22,0xe2b,0xe2b,0xe2b,0xe13,0xe13,0xe13,0xe13,0xe2b,0xe2b,0xe2b,
+0xe2b,0xe2b,0xe2b,0xe2b,0xe2b,0xe2b,0xe2b,0xe2b,0xe2b,0xe2b,0xe13,0xe25,0xe25,0xe13,0xe13,0xe28,
+0xe28,0xe28,0xe28,0xe28,0xe28,0xe16,0xe2b,0xe28,0xe1f,0xe1f,0xe1f,0xe1f,0xe1f,0xe1f,0xe1f,0xe1f,
+0xe1f,0xe1f,0xf87,0xf87,0xf84,0xf81,0xe1c,0xe1c,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,
+0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,
+0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3e1,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+0x3f,0x3f,0x3f,0x3f,0x3de,0x3de,0x3de,0x3de,0x3de,0x3de,0x3de,0x3de,0x3de,0x3de,0x3de,0x3de,
+0x3de,0x3de,0x3de,0x3de,0x3de,0x3de,0x3de,0x3de,0x3de,0x3de,0x3de,0xa26,0xa26,0xc24,0xc24,0x3db,
+0xc27,0x3f,0x3f,0x3f,0x714,0x714,0x714,0x714,0x714,0x714,0x714,0x714,0x714,0x714,0x714,0x714,
+0x714,0x714,0x714,0x714,0x714,0x714,0x714,0x714,0x714,0x714,0x714,0x714,0x714,0x714,0x714,0x714,
+0x714,0x714,0x714,0x714,0x714,0x714,0x10ec,0x10ec,0x10ec,0x10ec,0x10ec,0x717,0x3ea,0x3e7,0x3e7,0x3e7,
+0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,
+0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,0x3e7,
+0x3e7,0x3e7,0x3e7,0x10f2,0x10f2,0x10f2,0x10f2,0x10f2,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,
+0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,
+0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x3e4,0x10ef,0x10ef,0x10ef,0x10ef,0x10ef,0x10ef,
+0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0xc30,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,
+0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,
+0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0xc30,0x8f4,0x42,0x8f4,0x8f4,
+0x8f4,0x8f4,0x42,0x42,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x42,0x8f4,0x42,0x8f4,0x8f4,
+0x8f4,0x8f4,0x42,0x42,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0xc30,0x8f4,0x42,0x8f4,0x8f4,
+0x8f4,0x8f4,0x42,0x42,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,
+0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x42,0x8f4,0x8f4,0x8f4,0x8f4,0x42,0x42,0x8f4,0x8f4,0x8f4,0x8f4,
+0x8f4,0x8f4,0x8f4,0xc30,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x42,0x8f4,0x8f4,0x8f4,0x8f4,
+0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0xc30,0x8f4,0x8f4,0x8f4,0x8f4,
+0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0xc30,
+0x8f4,0x42,0x8f4,0x8f4,0x8f4,0x8f4,0x42,0x42,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0xc30,
+0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,0x8f4,
+0x8f4,0x8f4,0x8f4,0x42,0x42,0x42,0x42,0xc2a,0xc2d,0x8ee,0x8f7,0x8eb,0x8eb,0x8eb,0x8eb,0x8f7,
+0x8f7,0x8f1,0x8f1,0x8f1,0x8f1,0x8f1,0x8f1,0x8f1,0x8f1,0x8f1,0x8e8,0x8e8,0x8e8,0x8e8,0x8e8,0x8e8,
+0x8e8,0x8e8,0x8e8,0x8e8,0x8e8,0x42,0x42,0x42,0xc96,0xc96,0xc96,0xc96,0xc96,0xc96,0xc96,0xc96,
+0xc96,0xc96,0xc96,0xc96,0xc96,0xc96,0xc96,0xc96,0xc93,0xc93,0xc93,0xc93,0xc93,0xc93,0xc93,0xc93,
+0xc93,0xc93,0x102,0x102,0x102,0x102,0x102,0x102,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,
+0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,
+0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x8fa,0x45,0x45,0x45,0x45,0x45,0x45,0x45,
+0x45,0x45,0x45,0x45,0xf8a,0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x900,
+0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x900,
+0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x900,0x8fd,0x903,0x900,0x900,0x900,0x900,0x900,
+0x900,0x900,0x900,0xf8d,0xf8d,0xf8d,0xf8d,0xf8d,0xf8d,0xf8d,0xf8d,0xf8d,0x90c,0x90f,0x90f,0x90f,
+0x90f,0x90f,0x90f,0x90f,0x90f,0x90f,0x90f,0x90f,0x90f,0x90f,0x90f,0x90f,0x90f,0x90f,0x90f,0x90f,
+0x90f,0x90f,0x90f,0x90f,0x90f,0x90f,0x90f,0x909,0x906,0x48,0x48,0x48,0x915,0x915,0x915,0x915,
+0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,
+0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x915,0x912,
+0x912,0x912,0x915,0x915,0x915,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,0x4b,
+0x4b,0x4b,0x4b,0x4b,0xa8c,0xa8c,0xa8c,0xa8c,0xa8c,0xa8c,0xa8c,0xa8c,0xa8c,0xa8c,0xa8c,0xa8c,
+0xa8c,0xc0,0xa8c,0xa8c,0xa8c,0xa8c,0xa86,0xa86,0xa89,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,
+0xc0,0xc0,0xc0,0xc0,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,
+0xa98,0xa98,0xa98,0xa98,0xa98,0xa98,0xa92,0xa92,0xa95,0xa8f,0xa8f,0xc3,0xc3,0xc3,0xc3,0xc3,
+0xc3,0xc3,0xc3,0xc3,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,
+0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9e,0xa9b,0xa9b,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,
+0xc6,0xc6,0xc6,0xc6,0xaa4,0xaa4,0xaa4,0xaa4,0xaa4,0xaa4,0xaa4,0xaa4,0xaa4,0xaa4,0xaa4,0xaa4,
+0xaa4,0xc9,0xaa4,0xaa4,0xaa4,0xc9,0xaa1,0xaa1,0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,0xc9,
+0xc9,0xc9,0xc9,0xc9,0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x939,
+0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x939,
+0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x93c,0x93c,0x939,0x939,0x939,0x939,0x939,0x939,0x939,
+0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x939,0x918,0x918,0x936,0x91b,0x91b,0x91b,0x91b,0x91b,
+0x91b,0x91b,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x936,0x91b,0x936,0x936,0x91e,0x91e,0x91e,
+0x91e,0x91e,0x91e,0x91e,0x91e,0x91e,0x921,0x91e,0x92d,0x92d,0x930,0x939,0x927,0x924,0x92d,0x92a,
+0x939,0xb52,0x4e,0x4e,0x933,0x933,0x933,0x933,0x933,0x933,0x933,0x933,0x933,0x933,0x4e,0x4e,
+0x4e,0x4e,0x4e,0x4e,0xb55,0xb55,0xb55,0xb55,0xb55,0xb55,0xb55,0xb55,0xb55,0xb55,0x4e,0x4e,
+0x4e,0x4e,0x4e,0x4e,0x94b,0x94b,0x942,0x945,0x954,0x93f,0x951,0x94b,0x957,0x963,0x94b,0x966,
+0x966,0x966,0x94e,0x51,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x95a,0x51,0x51,
+0x51,0x51,0x51,0x51,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,
+0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,
+0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x960,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,
+0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,0x95d,
+0x95d,0x95d,0x95d,0x95d,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x95d,0x95d,0x95d,0x95d,
+0x95d,0x95d,0x95d,0x95d,0x95d,0x948,0xe2e,0x51,0x51,0x51,0x51,0x51,0xfcf,0xfcf,0xfcf,0xfcf,
+0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,
+0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0xfcf,0x165,0x165,
+0x165,0x165,0x165,0x165,0x165,0x165,0x165,0x165,0xb85,0xb85,0xb85,0xb85,0xb85,0xb85,0xb85,0xb85,
+0xb85,0xb85,0xb85,0xb85,0xb85,0xb85,0xb85,0xb85,0xb85,0xb85,0xb85,0xb85,0xb85,0xb85,0xb85,0xb85,
+0xb85,0xb85,0xb85,0xb85,0xb85,0xcf,0xcf,0xcf,0xb76,0xb76,0xb76,0xb82,0xb82,0xb82,0xb82,0xb76,
+0xb76,0xb82,0xb82,0xb82,0xcf,0xcf,0xcf,0xcf,0xb82,0xb82,0xb76,0xb82,0xb82,0xb82,0xb82,0xb82,
+0xb82,0xb79,0xb79,0xb79,0xcf,0xcf,0xcf,0xcf,0xb7c,0xcf,0xcf,0xcf,0xb88,0xb88,0xb7f,0xb7f,
+0xb7f,0xb7f,0xb7f,0xb7f,0xb7f,0xb7f,0xb7f,0xb7f,0xb8b,0xb8b,0xb8b,0xb8b,0xb8b,0xb8b,0xb8b,0xb8b,
+0xb8b,0xb8b,0xb8b,0xb8b,0xb8b,0xb8b,0xb8b,0xb8b,0xb8b,0xb8b,0xd2,0xd2,0xb8b,0xb8b,0xb8b,0xb8b,
+0xb8b,0xd2,0xd2,0xd2,0xd2,0xd2,0xd2,0xd2,0xd2,0xd2,0xd2,0xd2,0xcc0,0xcc0,0xcc0,0xcc0,
+0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,
+0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xfb4,0xfb4,
+0x10e,0x10e,0x10e,0x10e,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,
+0xcbd,0xcbd,0xcbd,0xcbd,0xcbd,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcc0,0xcbd,0xcbd,0x10e,0x10e,
+0x10e,0x10e,0x10e,0x10e,0xcba,0xcba,0xcba,0xcba,0xcba,0xcba,0xcba,0xcba,0xcba,0xcba,0xfb1,0x10e,
+0x10e,0x10e,0xcb7,0xcb7,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,
+0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,0xb8e,
+0xb8e,0xb8e,0xb8e,0xb8e,0xc7b,0xc7b,0xc7b,0xc7b,0xc7b,0xc7b,0xc7b,0xc7b,0xc7b,0xc7b,0xc7b,0xc7b,
+0xc7b,0xc7b,0xc7b,0xc7b,0xc7b,0xc7b,0xc7b,0xc7b,0xc7b,0xc7b,0xc7b,0xc72,0xc72,0xc78,0xc78,0xc78,
+0xf3,0xf3,0xc75,0xc75,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,
+0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,0xfea,
+0xfea,0xfea,0xfea,0xfea,0xfea,0xfe7,0xfd2,0xfe7,0xfd2,0xfd2,0xfd2,0xfd2,0xfd2,0xfd2,0xfd2,0x168,
+0xfdb,0xfe7,0xfd2,0xfe7,0xfe7,0xfd2,0xfd2,0xfd2,0xfd2,0xfd2,0xfd2,0xfd2,0xfd2,0xfe7,0xfe7,0xfe7,
+0xfe7,0xfe7,0xfe7,0xfd2,0xfd2,0xfd8,0xfd8,0xfd8,0xfd8,0xfd8,0xfd8,0xfd8,0xfd8,0x168,0x168,0xfd5,
+0xfe4,0xfe4,0xfe4,0xfe4,0xfe4,0xfe4,0xfe4,0xfe4,0xfe4,0xfe4,0x168,0x168,0x168,0x168,0x168,0x168,
+0xfe4,0xfe4,0xfe4,0xfe4,0xfe4,0xfe4,0xfe4,0xfe4,0xfe4,0xfe4,0x168,0x168,0x168,0x168,0x168,0x168,
+0xfde,0xfde,0xfde,0xfde,0xfde,0xfde,0xfde,0xfed,0xfe1,0xfe1,0xfe1,0xfe1,0xfde,0xfde,0x168,0x168,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xd83,0xd83,0xd83,0xd83,0xd95,0xd9e,0xda1,0xd9e,0xda1,0xd9e,0xda1,0xd9e,0xda1,0xd9e,0xda1,0xd9e,
+0xd9e,0xd9e,0xda1,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,
+0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd86,0xd95,0xd83,0xd83,0xd83,0xd83,0xd83,0xd98,
+0xd83,0xd98,0xd95,0xd95,0xd98,0xd98,0xd83,0xd98,0xd9b,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,0xd9e,
+0x123,0x123,0x123,0x123,0xd92,0xd92,0xd92,0xd92,0xd92,0xd92,0xd92,0xd92,0xd92,0xd92,0xda4,0xda4,
+0xd89,0xd8f,0xda4,0xda4,0xd8c,0xd89,0xd89,0xd89,0xd89,0xd89,0xd89,0xd89,0xd89,0xd89,0xd89,0xd86,
+0xd86,0xd86,0xd86,0xd86,0xd86,0xd86,0xd86,0xd86,0xd89,0xd89,0xd89,0xd89,0xd89,0xd89,0xd89,0xd89,
+0xd89,0x123,0x123,0x123,0xea6,0xea6,0xeac,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,
+0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,
+0xeb2,0xeb2,0xeb2,0xeb2,0xeb2,0xeac,0xea6,0xea6,0xea6,0xea6,0xeac,0xeac,0xea6,0xea6,0xeaf,0x138,
+0x138,0x138,0xeb2,0xeb2,0xea9,0xea9,0xea9,0xea9,0xea9,0xea9,0xea9,0xea9,0xea9,0xea9,0x138,0x138,
+0x138,0x138,0x138,0x138,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,
+0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,0xec7,
+0xec7,0xec7,0xec7,0xec7,0xec4,0xec4,0xec4,0xec4,0xec4,0xec4,0xec4,0xec4,0xeb5,0xeb5,0xeb5,0xeb5,
+0xeb5,0xeb5,0xeb5,0xeb5,0xec4,0xec4,0xebb,0xeb8,0x13b,0x13b,0x13b,0xeca,0xeca,0xebe,0xebe,0xebe,
+0xec1,0xec1,0xec1,0xec1,0xec1,0xec1,0xec1,0xec1,0xec1,0xec1,0x13b,0x13b,0x13b,0xec7,0xec7,0xec7,
+0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,0xecd,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,
+0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,0xed0,
+0xed0,0xed0,0xed0,0xed0,0xed3,0xed3,0xed3,0xed6,0xed3,0xed3,0xed9,0xed9,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xffc,0xffc,0xffc,0xff0,
+0xffc,0xffc,0xffc,0xffc,0xffc,0xffc,0xffc,0xffc,0xffc,0xffc,0xffc,0xffc,0xffc,0xff6,0xffc,0xffc,
+0xffc,0xffc,0xffc,0xffc,0xffc,0xff9,0xff9,0xff9,0xff9,0xffc,0xff9,0xff9,0xff9,0xff9,0xff3,0x16b,
+0x16b,0x16b,0x16b,0x16b,0x16b,0x16b,0x16b,0x16b,0x16b,0x16b,0x16b,0x16b,0xb9d,0xb9d,0xb9d,0xb9d,
+0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,
+0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb9d,0xb94,0xb94,
+0xb94,0xb94,0xb94,0xb91,0xba6,0xba6,0xba6,0xba0,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,
+0xba6,0xba6,0xba6,0xba0,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,
+0xba6,0xba6,0xba0,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,0xba6,
+0xba6,0xb9a,0xb9a,0xb9a,0xb9a,0xb9a,0xba3,0xba3,0xba3,0xba3,0xb97,0xb97,0xb97,0xb97,0xb97,0xb9d,
+0xc5d,0xc5d,0xc5d,0xc5d,0xc5d,0xc5d,0xc5d,0xc5d,0xc5d,0xc5d,0xc5d,0xc5d,0xc5a,0xc5d,0xc5d,0xc5d,
+0xc5d,0xc5d,0xc5d,0xc5d,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,
+0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccc,0xccf,
+0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,
+0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xccf,0xcc9,
+0xc7e,0xc7e,0xc7e,0xc7e,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xd65,0xe67,0xe67,0xe67,0xe67,0xe67,
+0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,0xe64,
+0xe64,0xe64,0xe64,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,
+0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa5,0xd65,0xd65,0x3f3,0x3ed,0x3f3,0x3ed,
+0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,
+0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3ed,0x3ed,
+0x3ed,0x3ed,0x3f0,0x834,0xe31,0xe31,0xe34,0xe31,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,
+0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,0x3f3,0x3ed,
+0x3f3,0x3ed,0xe34,0xe31,0xe34,0xe31,0xe34,0xe31,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,
+0x402,0x402,0x402,0x402,0x402,0x402,0x402,0x402,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x54,0x54,
+0x402,0x402,0x402,0x402,0x402,0x402,0x54,0x54,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,
+0x402,0x402,0x402,0x402,0x402,0x402,0x402,0x402,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,
+0x402,0x402,0x402,0x402,0x402,0x402,0x402,0x402,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x54,0x54,
+0x402,0x402,0x402,0x402,0x402,0x402,0x54,0x54,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,
+0x54,0x402,0x54,0x402,0x54,0x402,0x54,0x402,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,
+0x402,0x402,0x402,0x402,0x402,0x402,0x402,0x402,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,
+0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x54,0x54,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,
+0x402,0x402,0x402,0x402,0x402,0x402,0x402,0x402,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x54,0x3ff,0x3ff,
+0x402,0x402,0x402,0x402,0x402,0x3f9,0x3ff,0x3f9,0x3f9,0x3f6,0x3ff,0x3ff,0x3ff,0x54,0x3ff,0x3ff,
+0x402,0x402,0x402,0x402,0x402,0x3f6,0x3f6,0x3f6,0x3ff,0x3ff,0x3ff,0x3ff,0x54,0x54,0x3ff,0x3ff,
+0x402,0x402,0x402,0x402,0x54,0x3f6,0x3f6,0x3f6,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,0x3ff,
+0x402,0x402,0x402,0x402,0x402,0x3f6,0x3f6,0x3f6,0x54,0x54,0x3ff,0x3ff,0x3ff,0x54,0x3ff,0x3ff,
+0x402,0x402,0x402,0x402,0x402,0x3fc,0x3f9,0x54,0x40e,0x40e,0x411,0x411,0x411,0x411,0x411,0x414,
+0x411,0x411,0x411,0x408,0x44d,0x44d,0x44a,0x44a,0x5cd,0x432,0x42f,0x5ca,0x5c7,0x5c4,0x5d6,0x420,
+0x5d3,0x5d3,0x435,0x438,0x5d0,0x5d0,0x435,0x438,0x5af,0x5af,0x5b2,0x41d,0x5be,0x5bb,0x5bb,0x5b8,
+0x447,0x447,0x405,0x405,0x405,0x405,0x405,0x969,0x5c1,0x429,0x5d9,0x5dc,0x43e,0x5c1,0x42c,0x42c,
+0x41d,0x438,0x438,0x5af,0x444,0x441,0x5b5,0x417,0x41a,0x41d,0x41d,0x41d,0x43b,0x426,0x423,0xa3b,
+0x96f,0x96f,0x96c,0x96c,0x96c,0x96c,0xa32,0xa32,0xa32,0xa32,0xa38,0xb5b,0xb58,0xc33,0xc36,0xa35,
+0xc36,0xc36,0xc36,0xc36,0xc33,0xc36,0xc36,0xa2f,0xa29,0xa2c,0xa2c,0xa2c,0xe37,0x57,0x57,0x57,
+0x57,0x57,0x40b,0x40b,0x40b,0x40b,0x40b,0x40b,0x453,0xa3e,0x5a,0x5a,0x5e2,0x453,0x453,0x453,
+0x453,0x453,0x459,0x46b,0x459,0x465,0x45f,0x5e5,0x450,0x5df,0x5df,0x5df,0x5df,0x450,0x450,0x450,
+0x450,0x450,0x456,0x468,0x456,0x462,0x45c,0x5a,0xc39,0xc39,0xc39,0xc39,0xc39,0x5a,0x5a,0x5a,
+0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x471,0x471,0x471,0x471,0x471,0x471,0x471,0x46e,
+0x474,0x645,0x471,0x837,0x858,0x972,0x972,0x972,0xa41,0xa41,0xc3c,0xc3c,0xc3c,0xc3c,0xf90,0xf93,
+0xf93,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,0x5d,
+0x5d,0x5d,0x5d,0x5d,0x47a,0x47a,0x47a,0x47a,0x47a,0x47a,0x47a,0x47a,0x47a,0x47a,0x47a,0x47a,
+0x47a,0x477,0x477,0x477,0x477,0x47a,0x975,0x975,0xa44,0xa4a,0xa4a,0xa47,0xa47,0xa47,0xa47,0xc3f,
+0xd3e,0xd3e,0xd3e,0xd3e,0xe3a,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
+0x60,0x60,0x60,0x60,0x480,0x480,0x495,0x5ee,0x47d,0x5e8,0x480,0x48c,0x47d,0x5ee,0x48f,0x495,
+0x495,0x495,0x48f,0x48f,0x495,0x495,0x495,0x5f4,0x47d,0x495,0x5f1,0x47d,0x489,0x495,0x495,0x495,
+0x495,0x495,0x47d,0x47d,0x483,0x5e8,0x5eb,0x47d,0x495,0x47d,0x5f7,0x47d,0x495,0x486,0x49b,0x5fa,
+0x495,0x495,0x489,0x48f,0x495,0x495,0x498,0x495,0x48f,0x492,0x492,0x492,0x492,0x97b,0x978,0xb5e,
+0xc45,0xa56,0xa59,0xa59,0xa53,0xa50,0xa50,0xa50,0xa50,0xa59,0xa56,0xa56,0xa56,0xa56,0xa4d,0xa50,
+0xc42,0xd41,0xd44,0xe3d,0xf96,0xf96,0xf96,0x600,0x5fd,0x49e,0x4a1,0x4a1,0x4a1,0x4a1,0x4a1,0x5fd,
+0x600,0x600,0x5fd,0x4a1,0x606,0x606,0x606,0x606,0x606,0x606,0x606,0x606,0x606,0x606,0x606,0x606,
+0x4aa,0x4aa,0x4aa,0x4aa,0x603,0x603,0x603,0x603,0x603,0x603,0x603,0x603,0x603,0x603,0x4a4,0x4a4,
+0x4a4,0x4a4,0x4a4,0x4a4,0x4a7,0x4a7,0x4a7,0x97e,0xd47,0xe40,0xe40,0xe40,0xe40,0x10d1,0x63,0x63,
+0x63,0x63,0x63,0x63,0x60c,0x60c,0x60c,0x60c,0x60c,0x60c,0x60c,0x60c,0x60c,0x60c,0x4b3,0x4b3,
+0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4ad,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b3,0x4ad,
+0x4b0,0x4b0,0x4ad,0x4ad,0x4ad,0x4ad,0x4b0,0x4b0,0x609,0x609,0x4ad,0x4ad,0x4b0,0x4b0,0x4b0,0x4b0,
+0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b3,0x4b3,0x4b3,0x4b0,0x4b0,0x60c,0x4b0,
+0x60c,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4b0,0x4ad,0x4b0,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,0x4ad,
+0x4b0,0x4b0,0x4ad,0x609,0x4ad,0x4ad,0x4ad,0x981,0x981,0x981,0x981,0x981,0x981,0x981,0x981,0x981,
+0xa5c,0xa5c,0xa5c,0xa5c,0xa5c,0xa5c,0xa5c,0xa5c,0xa5c,0xa5c,0xa5c,0xa5c,0x60f,0x4b6,0x60f,0x60f,
+0x4b9,0x4b6,0x4b6,0x60f,0x60f,0x4b9,0x4b6,0x60f,0x4b9,0x4b6,0x4b6,0x60f,0x4b6,0x60f,0x4c2,0x4bf,
+0x4b6,0x60f,0x4b6,0x4b6,0x4b6,0x4b6,0x60f,0x4b6,0x4b6,0x60f,0x60f,0x60f,0x60f,0x4b6,0x4b6,0x60f,
+0x4b9,0x60f,0x4b9,0x60f,0x60f,0x60f,0x60f,0x60f,0x615,0x4bc,0x60f,0x4bc,0x4bc,0x4b6,0x4b6,0x4b6,
+0x60f,0x60f,0x60f,0x60f,0x4b6,0x4b6,0x4b6,0x4b6,0x60f,0x60f,0x4b6,0x4b6,0x4b6,0x4b9,0x4b6,0x4b6,
+0x4b9,0x4b6,0x4b6,0x4b9,0x60f,0x4b9,0x4b6,0x4b6,0x60f,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x60f,0x4b6,
+0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x612,0x60f,0x4b9,0x4b6,
+0x60f,0x60f,0x60f,0x60f,0x4b6,0x4b6,0x60f,0x60f,0x4b6,0x4b9,0x612,0x612,0x4b9,0x4b9,0x4b6,0x4b6,
+0x4b9,0x4b9,0x4b6,0x4b6,0x4b9,0x4b9,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b9,0x4b9,0x60f,0x60f,
+0x4b9,0x4b9,0x60f,0x60f,0x4b9,0x4b9,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,
+0x4b6,0x60f,0x4b6,0x4b6,0x4b6,0x60f,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x60f,0x4b6,0x4b6,
+0x4b6,0x4b6,0x4b6,0x4b6,0x4b9,0x4b9,0x4b9,0x4b9,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,
+0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x60f,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,
+0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,
+0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b6,0x4b9,0x4b9,0x4b9,0x4b9,0x4b6,0x4b6,0x4b6,0x4b6,
+0x4b6,0x4b6,0x4b9,0x4b9,0x4b9,0x4b9,0x4b6,0x4b6,0x4b6,0x4b6,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,
+0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0xa5f,0x4c5,0x984,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,
+0x4c8,0x4c8,0x4c8,0x4c8,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x618,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,
+0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c8,0x4c8,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,
+0x4c5,0x71d,0x71a,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,
+0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,
+0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x4c5,0x984,0xa65,0x984,0x984,0x984,0x984,0x984,0x984,0x984,
+0x984,0x984,0x984,0x984,0x984,0x984,0x984,0x984,0x984,0x984,0x984,0x984,0x984,0x984,0x984,0x984,
+0x984,0x984,0x984,0x984,0x984,0x984,0x984,0xa65,0xa65,0xa65,0xa65,0xa65,0xa65,0xa65,0xa65,0xa65,
+0xa65,0xa65,0xa65,0xa65,0xa65,0xa65,0xa65,0xa65,0xa65,0xa65,0xa65,0xa65,0xa65,0xa65,0xa62,0xa65,
+0xa62,0xa62,0xa62,0xa62,0xa62,0xa62,0xa62,0xa62,0xa62,0xa62,0xa62,0xa62,0xa62,0xa62,0xa62,0xb61,
+0xb64,0xc48,0xc48,0xc48,0xc48,0xc48,0xc48,0xc48,0xc48,0xc48,0xc48,0xc48,0xd4d,0xd4d,0xd4d,0xd4d,
+0xd4d,0xd4d,0xd4d,0xd4a,0xd4a,0xd4a,0xd4a,0xd4a,0xf99,0x66,0x66,0x66,0x66,0x66,0x66,0x66,
+0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,
+0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,
+0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,0x4cb,
+0x4cb,0x987,0x987,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,
+0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x69,0x4ce,0x4ce,0x4ce,0x4ce,
+0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x4ce,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,
+0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x61e,0x61e,0x61e,0x61e,
+0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,0x61e,
+0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,
+0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,0x61b,
+0x61b,0x61b,0x624,0x624,0x624,0x624,0x624,0x624,0x624,0x624,0x624,0x624,0x624,0x624,0x624,0x624,
+0x624,0x624,0x624,0x624,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,0x621,
+0x621,0x621,0x621,0x621,0x621,0x621,0x4d1,0xac8,0xac8,0xac8,0xac8,0xac8,0xac8,0xac8,0xac8,0xac8,
+0xac8,0xac8,0xac8,0xac8,0xac8,0xac8,0xac8,0xac8,0xac8,0xac8,0xac8,0xbd6,0x627,0x627,0x627,0x627,
+0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,
+0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x4d7,0x4d7,0x4d7,0x4d7,
+0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,0x627,
+0x627,0x627,0x627,0x627,0x4d4,0x4d7,0x4d7,0x4d7,0x4d7,0x4d7,0x4d7,0x4d7,0x4d7,0x4d7,0x4d7,0x4d7,
+0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,0x62a,
+0x4da,0x4da,0x62a,0x62a,0x62a,0x62a,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,0xa68,
+0x630,0x630,0x4dd,0x62d,0x62d,0x62d,0x62d,0x62d,0x62d,0x62d,0x4dd,0x4dd,0x4dd,0x4dd,0x4e0,0x4e0,
+0x4e0,0x4e0,0x630,0x630,0x4e0,0x4e0,0x630,0x630,0x4dd,0x4dd,0x4dd,0x4dd,0x630,0x630,0x4e0,0x4e0,
+0x630,0x630,0x4dd,0x4dd,0x4dd,0x4dd,0x630,0x630,0x62d,0x4dd,0x4e0,0x630,0x4dd,0x4dd,0x62d,0x630,
+0x630,0x630,0x4e0,0x4e0,0x4dd,0x4dd,0x4dd,0x4dd,0x4dd,0x4dd,0x4dd,0x4dd,0x4dd,0x4dd,0x4dd,0x4dd,
+0x4dd,0x4dd,0x630,0x62d,0x630,0x62d,0x4dd,0x4e0,0x4e0,0x4e0,0x4e0,0x4e0,0x4e0,0x4dd,0x4dd,0x62d,
+0x98a,0x98a,0x98a,0x98a,0x98a,0x98a,0x98a,0x98a,0xa6b,0xa6b,0xa6b,0xa6b,0xa6b,0xa6b,0xa6b,0xa6b,
+0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x636,0x636,0x4e3,0x4e3,0x633,0x4e3,0x4e3,0x4e3,0x4e3,0x633,0x633,
+0x4e3,0x4e3,0x4e3,0x4e3,0xbd9,0xbd9,0xa6e,0xa6e,0xc4b,0x98d,0x4e3,0x4e3,0x633,0x4e3,0x633,0x4e3,
+0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,
+0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,
+0x636,0x4e3,0x636,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,
+0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,0x4e3,
+0x636,0x636,0x4e6,0x636,0x633,0x633,0x4e3,0x633,0x633,0x633,0x633,0x4e3,0x633,0x636,0x4e6,0x636,
+0x98d,0x98d,0xa71,0xa71,0xa71,0xa71,0xa71,0xa71,0xa71,0xa71,0xa71,0xa71,0xa71,0xa71,0xc4b,0xc4b,
+0xa71,0xa71,0xa71,0xa71,0xa71,0xa71,0xa71,0xa71,0xa71,0xa71,0xb67,0xb67,0xb67,0xb67,0xb67,0xb67,
+0xb67,0xb67,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xe43,0x10d4,0x10d4,
+0xb67,0xb67,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,0xc4b,
+0xc4b,0xc4b,0xd50,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xe43,0xf9c,0x10d4,0x10d4,
+0xe43,0xe43,0xe43,0xe43,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x6f,0x10d4,
+0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,
+0x10d4,0x10d4,0x6f,0x10d4,0x6f,0x6f,0x6f,0x6f,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,
+0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,0x10d4,
+0x72,0x4ec,0x4ec,0x4ec,0x4ec,0x72,0x4ec,0x4ec,0x4ec,0x4ec,0x72,0x72,0x4ec,0x4ec,0x4ec,0x4ec,
+0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,
+0x72,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,
+0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x63c,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,
+0x4ec,0x4ec,0x4ec,0x4ec,0x72,0x4ec,0x72,0x4ec,0x4ec,0x4ec,0x4ec,0x72,0x72,0x72,0x4ec,0x10d7,
+0x4ec,0x4ec,0x4ec,0x4f2,0x4f2,0x4f2,0x4f2,0x72,0x72,0x4ec,0x4ef,0x4ef,0x4ec,0x4ec,0x4ec,0x4ec,
+0xa77,0xa74,0xa77,0xa74,0xa77,0xa74,0xa77,0xa74,0xa77,0xa74,0xa77,0xa74,0xa77,0xa74,0x639,0x639,
+0x639,0x639,0x639,0x639,0x639,0x639,0x639,0x639,0x4e9,0x4e9,0x4e9,0x4e9,0x4e9,0x4e9,0x4e9,0x4e9,
+0x4e9,0x4e9,0x4e9,0x4e9,0x4e9,0x4e9,0x4e9,0x4e9,0x4e9,0x4e9,0x4e9,0x4e9,0x4ec,0x72,0x72,0x72,
+0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,
+0x72,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x4ec,0x72,
+0xc51,0xc51,0xc51,0xc51,0xc51,0xc57,0xc54,0xd5f,0xd5f,0xd5f,0xd5f,0xcc,0xe52,0xcc,0xcc,0xcc,
+0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,0xaa7,
+0xaa7,0xaa7,0xad7,0xad4,0xad7,0xad4,0xad7,0xad4,0xf66,0xf63,0xe58,0xe55,0xaaa,0xaaa,0xaaa,0xaaa,
+0xaaa,0xaaa,0xaaa,0xaaa,0xaaa,0xaaa,0xaaa,0xaaa,0xaaa,0xaaa,0xaaa,0xaaa,0x990,0x990,0x990,0x990,
+0x990,0x990,0x990,0x990,0x990,0x990,0x990,0x990,0x990,0x990,0x990,0x990,0x990,0x990,0x990,0x990,
+0x990,0x990,0x990,0x990,0x990,0x990,0x990,0x990,0x990,0x990,0x990,0x990,0xaad,0xaad,0xaad,0xaad,
+0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,
+0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xaad,0xab0,0xab0,0xab0,0xab6,
+0xab3,0xadd,0xada,0xab6,0xab3,0xab6,0xab3,0xab6,0xab3,0xab6,0xab3,0xab6,0xab3,0xab6,0xab3,0xab6,
+0xab3,0xab6,0xab3,0xab6,0xab3,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,
+0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,
+0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab6,0xab3,0xab6,0xab3,0xab0,0xab0,0xab0,0xab0,
+0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,
+0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab0,0xab6,0xab3,0xab0,0xab0,0xab9,0xab9,0xab9,0xab9,
+0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xabf,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,
+0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,
+0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xabf,0xabf,0xabf,0xab9,
+0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,
+0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xab9,0xabc,0xab9,0xab9,0xab9,
+0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xba9,0xc60,0xc60,
+0xc60,0xc60,0xc60,0xc60,0xd62,0xd62,0xd62,0xd62,0xd62,0xd62,0xd62,0xe5b,0xe5b,0xe5b,0xe5b,0xe5b,
+0xd62,0xd62,0xd62,0xd62,0xe5b,0xe5b,0xe5b,0xe5b,0xe5b,0xe5b,0xe5b,0xe5b,0xe5b,0xe5b,0xe5b,0xe5b,
+0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,
+0xe5e,0xe5b,0xe5b,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xe5e,0xd5,0xd5,0xd5,0xe5b,0xe5b,0xe5b,0xe5b,
+0xe5b,0x10dd,0x10dd,0x10dd,0x10dd,0x10dd,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,
+0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,
+0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xd5,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,
+0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,
+0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0xc9f,0x108,0xc9c,0xc9c,0xc9c,0xc9c,
+0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,
+0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0xc9c,0x108,0xdaa,0xda7,0xdaa,0xdaa,
+0xdaa,0xda7,0xda7,0xdaa,0xda7,0xdaa,0xda7,0xdaa,0xda7,0xe91,0xe91,0xe91,0xfba,0xe88,0xe91,0xe88,
+0xda7,0xdaa,0xda7,0xda7,0xe88,0xe88,0xe88,0xe88,0xe8b,0xe8e,0xfba,0xfba,0xc8d,0xc8a,0xc8d,0xc8a,
+0xc8d,0xc8a,0xc8d,0xc8a,0xc8d,0xc8a,0xc8d,0xc8a,0xc8d,0xc8a,0xc8d,0xc8a,0xc8d,0xc8a,0xc8d,0xc8a,
+0xc8d,0xc8a,0xc8d,0xc8a,0xc8d,0xc8a,0xc8d,0xc8a,0xc8d,0xc8a,0xc8d,0xc8a,0xc8a,0xc81,0xc81,0xc81,
+0xc81,0xc81,0xc81,0xfae,0xfab,0xfae,0xfab,0xfa8,0xfa8,0xfa8,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,
+0xfc,0xc87,0xc84,0xc84,0xc84,0xc81,0xc87,0xc84,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,
+0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,
+0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0xc99,0x105,0x105,0x105,0x105,0x105,0x105,
+0x105,0x105,0x105,0x105,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,
+0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,
+0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0xcf0,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0xcf3,
+0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,0x11a,
+0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,
+0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xff,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xff,
+0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xff,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xc90,0xff,
+0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,
+0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,0xedc,
+0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd8,0xcd5,0xcd5,
+0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd5,0xcd2,0xcdb,0xe76,0xe70,0xe7f,0xe6d,0xcd8,0xcd8,0xe6d,0xe6d,
+0xe7c,0xe7c,0xe79,0xe73,0xe79,0xe73,0xe79,0xe73,0xe79,0xe73,0xe70,0xe70,0xe70,0xe70,0xe85,0xe82,
+0xe70,0xfb7,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,
+0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,0x114,
+0x114,0x114,0x114,0x114,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,
+0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x75,0x9a2,
+0x9a2,0x9a2,0x9a2,0x9a5,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,
+0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,
+0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a2,0x9a5,0x75,0x75,0x75,0x75,0x75,0x75,0x75,0x75,
+0x75,0x75,0x75,0x75,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,
+0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,
+0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x9a8,0x78,0x78,0x78,0x78,0x78,0x78,0x78,0x78,0x78,0x78,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x9ab,0x9ab,0x9ae,0x9ae,0x9ab,0x9ab,0x9ab,0x9ab,0x9ab,0x9ab,0x9ab,0x9ab,0x7b,0x7b,0x7b,0x7b,
+0x66f,0x741,0x744,0x72f,0x720,0x74d,0x726,0x74a,0x732,0x72c,0x732,0x72c,0x73e,0x73b,0x73e,0x73b,
+0x732,0x72c,0x72f,0x72f,0x732,0x72c,0x732,0x72c,0x732,0x72c,0x732,0x72c,0x738,0x73e,0x73b,0x73b,
+0x72f,0x74a,0x74a,0x74a,0x74a,0x74a,0x74a,0x74a,0x74a,0x74a,0x747,0x747,0x747,0x747,0x747,0x747,
+0x735,0x729,0x729,0x729,0x729,0x729,0x723,0x720,0x9b4,0x9b4,0x9b4,0xae6,0xae3,0xae0,0x9b1,0x4f5,
+0x7e,0x75c,0x756,0x75c,0x756,0x75c,0x756,0x75c,0x756,0x75c,0x756,0x756,0x759,0x756,0x759,0x756,
+0x759,0x756,0x759,0x756,0x759,0x756,0x759,0x756,0x759,0x756,0x759,0x756,0x759,0x756,0x759,0x756,
+0x759,0x756,0x759,0x75c,0x756,0x759,0x756,0x759,0x756,0x759,0x756,0x756,0x756,0x756,0x756,0x756,
+0x759,0x759,0x756,0x759,0x759,0x756,0x759,0x759,0x756,0x759,0x759,0x756,0x759,0x759,0x756,0x756,
+0x756,0x756,0x756,0x75c,0x756,0x75c,0x756,0x75c,0x756,0x756,0x756,0x756,0x756,0x756,0x75c,0x756,
+0x756,0x756,0x756,0x756,0x759,0xaec,0xaec,0x7e,0x7e,0x753,0x753,0x750,0x750,0x75f,0x762,0xae9,
+0xaef,0x771,0x76b,0x771,0x76b,0x771,0x76b,0x771,0x76b,0x771,0x76b,0x76b,0x76e,0x76b,0x76e,0x76b,
+0x76e,0x76b,0x76e,0x76b,0x76e,0x76b,0x76e,0x76b,0x76e,0x76b,0x76e,0x76b,0x76e,0x76b,0x76e,0x76b,
+0x76e,0x76b,0x76e,0x771,0x76b,0x76e,0x76b,0x76e,0x76b,0x76e,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,
+0x76e,0x76e,0x76b,0x76e,0x76e,0x76b,0x76e,0x76e,0x76b,0x76e,0x76e,0x76b,0x76e,0x76e,0x76b,0x76b,
+0x76b,0x76b,0x76b,0x771,0x76b,0x771,0x76b,0x771,0x76b,0x76b,0x76b,0x76b,0x76b,0x76b,0x771,0x76b,
+0x76b,0x76b,0x76b,0x76b,0x76e,0x771,0x771,0x76e,0x76e,0x76e,0x76e,0x765,0x768,0x774,0x777,0xaf2,
+0x81,0x81,0x81,0x81,0x81,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,
+0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,0x77a,
+0x77a,0xf69,0x81,0x81,0x84,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,
+0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,
+0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x780,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,
+0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,
+0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x77d,0x84,0x783,0x783,0x786,0x786,0x786,0x786,0x786,0x786,
+0x786,0x786,0x786,0x786,0x786,0x786,0x786,0x786,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,
+0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,0x9b7,
+0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87,0xd05,0xd05,0xd05,0xd05,0xd05,0xd05,0xd05,0xd05,
+0xd05,0xd05,0xd05,0xd05,0xd05,0xd05,0xd05,0xd05,0xf6f,0xf6f,0xf6f,0xf6f,0xf6f,0xf6f,0xf6f,0xf6f,
+0xf6f,0xf6f,0xf6f,0xf6f,0xf6f,0xf6f,0xf6f,0xf6f,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,
+0xf6,0xf6,0xf6,0xf6,0xb01,0xb01,0xb01,0xb01,0xb01,0xb01,0xb01,0xb01,0xb01,0xb01,0xb01,0xb01,
+0xb01,0xb01,0xb01,0xb01,0x792,0x792,0x792,0x792,0x792,0x792,0x792,0x792,0x792,0x792,0x792,0x792,
+0x792,0x792,0x792,0x792,0x792,0x792,0x792,0x792,0x792,0x792,0x792,0x792,0x792,0x792,0x792,0x792,
+0x792,0xbe2,0xbe2,0x8a,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,
+0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,
+0x78c,0x78c,0x78c,0x78c,0x10f5,0x10f5,0x10f5,0x10f5,0x10da,0x10da,0x10da,0x10da,0x10da,0x10da,0x10da,0x10da,
+0xbdf,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,
+0x795,0x795,0x795,0x795,0x795,0x795,0x795,0x795,0x795,0x795,0x795,0x795,0x795,0x795,0x795,0x795,
+0x795,0x795,0x795,0x795,0x795,0x795,0x795,0x795,0x795,0x795,0x795,0x795,0xbe5,0xbe5,0xcfc,0x789,
+0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,
+0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,0x78f,
+0x78f,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,0xaf5,
+0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0x78c,0xbdf,0xbdf,0xbdf,0xbdf,
+0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,
+0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x798,0x8a,
+0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,
+0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,0x7a1,
+0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,
+0x79b,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0xbe8,0xbe8,0xbe8,0xbe8,0x79e,0x79e,0x79e,0x79e,0x79e,
+0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,
+0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0x79e,0xbe8,0xbe8,
+0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,
+0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0x79b,0xbe8,
+0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,
+0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,0x9ba,
+0x9ba,0x9ba,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0x1aa,0xbac,0xbac,0xbac,0xbac,
+0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,
+0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0xbac,0x7a4,0x7a4,0x7a4,0x7a4,
+0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,
+0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0x7a4,0xcff,0xcff,
+0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,0xcff,
+0xcff,0xcff,0xcff,0xcff,0xf6c,0xf6c,0xf6c,0xf6c,0x10f8,0x10f8,0x10f8,0x10f8,0x10f8,0x10f8,0x10f8,0x10f8,
+0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,
+0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,0x1ad,
+0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,
+0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9c0,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,
+0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,
+0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x9bd,0x8d,0x8d,0x8d,0x9c3,0x9c3,0x9c3,0x9c3,
+0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0xaf8,0xaf8,
+0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,
+0xaf8,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0x9c3,0xaf8,0x9c3,0x9c3,
+0x9c3,0xaf8,0x9c3,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x1002,0x1002,0x1002,0x1002,
+0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,
+0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0x1002,0xfff,0x1005,0xee5,0xee5,0xee5,0xee5,
+0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,
+0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee8,0xedf,0xeee,0xeeb,
+0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,0xee5,
+0xee2,0xee2,0xee2,0xee2,0xee2,0xee2,0xee2,0xee2,0xee2,0xee2,0xee5,0xee5,0x13e,0x13e,0x13e,0x13e,
+0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,0x13e,
+0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,
+0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,
+0x141,0x141,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xefd,0xef4,
+0xef1,0xef1,0xef1,0xef7,0x141,0x141,0x141,0x141,0x141,0x141,0x141,0x141,0xef4,0xef4,0xef7,0xf03,
+0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,
+0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0xf00,0xefa,0x141,0x141,0x141,0x141,0x141,0x141,0x141,0x141,
+0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,
+0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,0x1011,
+0x1008,0x1008,0x100b,0x1014,0x100e,0x100e,0x100e,0x1014,0x16e,0x16e,0x16e,0x16e,0x16e,0x16e,0x16e,0x16e,
+0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,
+0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xcb4,0xd68,0xd68,0xd68,0xd68,0xe6a,0xe6a,0xe6a,0xe6a,0xe6a,
+0xdad,0xdad,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,
+0xe9a,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,
+0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,
+0xea3,0xe9a,0xea3,0xe9a,0xe9d,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xe9a,0xea3,0xe9a,0xea3,
+0xe9a,0xea3,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xea3,0xe9a,0xe97,0xe94,0xe94,0xea3,
+0xe9a,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,
+0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,0x126,
+0x126,0x126,0x126,0x126,0x126,0x126,0x126,0xea0,0xea0,0xea0,0xea0,0xea0,0xced,0xced,0xcde,0xced,
+0xced,0xced,0xce4,0xced,0xced,0xced,0xced,0xcde,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,
+0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xced,0xcea,
+0xcea,0xce1,0xce1,0xcea,0xce7,0xce7,0xce7,0xce7,0x117,0x117,0x117,0x117,0x1017,0x1017,0x1017,0x1017,
+0x1017,0x1017,0x1017,0x1017,0x101a,0x1017,0x171,0x171,0x171,0x171,0x171,0x171,0xdb3,0xdb3,0xdb3,0xdb3,
+0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,
+0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb3,0xdb0,0xdb0,0xdb6,0xdb6,
+0x129,0x129,0x129,0x129,0x129,0x129,0x129,0x129,0xf0c,0xf0c,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,
+0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,
+0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0f,0xf0c,0xf0c,0xf0c,0xf0c,0xf0c,0xf0c,0xf0c,0xf0c,
+0xf0c,0xf0c,0xf0c,0xf0c,0xf06,0x144,0x144,0x144,0x144,0x144,0x144,0x144,0x144,0x144,0xf12,0xf12,
+0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,0xf09,0x144,0x144,0x144,0x144,0x144,0x144,
+0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,0x101d,
+0x101d,0x101d,0x1023,0x1023,0x1023,0x1023,0x1023,0x1023,0x1020,0x1020,0x1020,0x1023,0x174,0x174,0x174,0x174,
+0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf1e,0xf21,0xf21,0xf21,0xf21,0xf21,0xf21,
+0xf21,0xf21,0xf21,0xf21,0xf21,0xf21,0xf21,0xf21,0xf21,0xf21,0xf21,0xf21,0xf21,0xf21,0xf21,0xf21,
+0xf21,0xf21,0xf15,0xf15,0xf15,0xf15,0xf15,0xf18,0xf18,0xf18,0xf1b,0xf24,0xf33,0xf33,0xf33,0xf33,
+0xf33,0xf33,0xf33,0xf33,0xf33,0xf33,0xf33,0xf33,0xf33,0xf33,0xf33,0xf33,0xf33,0xf33,0xf33,0xf27,
+0xf27,0xf27,0xf27,0xf27,0xf27,0xf27,0xf27,0xf27,0xf27,0xf27,0xf2d,0xf30,0x147,0x147,0x147,0x147,
+0x147,0x147,0x147,0x147,0x147,0x147,0x147,0xf2a,0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,
+0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,
+0x10fe,0x10fe,0x10fe,0x10fe,0x10fe,0x177,0x177,0x177,0x1026,0x1026,0x1026,0x1035,0x103b,0x103b,0x103b,0x103b,
+0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,
+0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x103b,0x1029,0x1035,0x1035,0x1026,0x1026,
+0x1026,0x1026,0x1035,0x1035,0x1026,0x1035,0x1035,0x1035,0x1038,0x102c,0x102c,0x102c,0x102c,0x102c,0x102c,0x102f,
+0x1041,0x1041,0x102c,0x102c,0x102c,0x102c,0x17a,0x103e,0x1032,0x1032,0x1032,0x1032,0x1032,0x1032,0x1032,0x1032,
+0x1032,0x1032,0x17a,0x17a,0x17a,0x17a,0x102c,0x102c,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,
+0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,
+0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf36,0xf36,0xf36,0xf36,0xf36,0xf36,0xf3f,
+0xf3f,0xf36,0xf36,0xf3f,0xf3f,0xf36,0xf36,0x14a,0x14a,0x14a,0x14a,0x14a,0x14a,0x14a,0x14a,0x14a,
+0xf42,0xf42,0xf42,0xf36,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf42,0xf36,0xf3f,0x14a,0x14a,
+0xf3c,0xf3c,0xf3c,0xf3c,0xf3c,0xf3c,0xf3c,0xf3c,0xf3c,0xf3c,0x14a,0x14a,0xf39,0xf45,0xf45,0xf45,
+0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,
+0x104d,0x104a,0x104a,0x104a,0x104a,0x104a,0x104a,0x1044,0x1044,0x1044,0x104a,0x1047,0x17d,0x17d,0x17d,0x17d,
+0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,
+0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,0x105c,
+0x1050,0x105c,0x1050,0x1050,0x1050,0x1065,0x1065,0x1050,0x1050,0x1065,0x105c,0x1065,0x1065,0x105c,0x1050,0x1053,
+0x105f,0x1053,0x105f,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,
+0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x180,0x105c,0x105c,0x1062,0x1056,0x1059,
+0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,
+0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,0x1077,
+0x1077,0x1077,0x1077,0x1071,0x1071,0x1068,0x1071,0x1071,0x1068,0x1071,0x1071,0x107a,0x1074,0x106b,0x183,0x183,
+0x106e,0x106e,0x106e,0x106e,0x106e,0x106e,0x106e,0x106e,0x106e,0x106e,0x183,0x183,0x183,0x183,0x183,0x183,
+0x84f,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,
+0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x84f,0x852,0x852,0x852,
+0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,
+0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x852,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,
+0x93,0x93,0x93,0x93,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,
+0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x1104,0x186,0x186,0x186,0x186,0x1101,0x1101,0x1101,0x1101,0x1101,
+0x1101,0x1101,0x1101,0x1101,0x1101,0x1101,0x1101,0x1101,0x1101,0x1101,0x1101,0x1101,0x1101,0x1101,0x1101,0x1101,
+0x1101,0x1101,0x1101,0x1101,0x1101,0x1101,0x1101,0x1101,0x186,0x186,0x186,0x186,0x83a,0x83a,0x83a,0x83a,
+0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,
+0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83a,0x83d,0x83d,0x83d,0x83d,
+0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,
+0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x83d,0x840,0x840,0x840,0x840,
+0x840,0x840,0x840,0x840,0x840,0x840,0x840,0x840,0x840,0x840,0x840,0x840,0x840,0x840,0x840,0x840,
+0x840,0x840,0x840,0x840,0x840,0x840,0x840,0x840,0x840,0x840,0x840,0x840,0x63f,0x63f,0x63f,0x63f,
+0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,
+0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x63f,0x7a7,0x7a7,0x7a7,0x7a7,
+0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,
+0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7aa,0x7aa,
+0x7a7,0x7aa,0x7a7,0x7aa,0x7aa,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7a7,0x7aa,
+0x7a7,0x7aa,0x7a7,0x7aa,0x7aa,0x7a7,0x7a7,0x7aa,0x7aa,0x7aa,0x7a7,0x7a7,0x7a7,0x7a7,0x1b0,0x1b0,
+0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,
+0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,0xafb,
+0xafb,0xafb,0xafb,0x10fb,0x10fb,0x10fb,0x1b0,0x1b0,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,
+0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,
+0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0xd02,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,
+0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,
+0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x1b0,0x50a,0x50a,0x50a,0x50a,
+0x50a,0x50a,0x50a,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x96,0x4f8,
+0x4f8,0x4f8,0x4f8,0x4f8,0x96,0x96,0x96,0x96,0x96,0x993,0x4fb,0x501,0x507,0x507,0x507,0x507,
+0x507,0x507,0x507,0x507,0x507,0x4fe,0x501,0x501,0x501,0x501,0x501,0x501,0x501,0x501,0x501,0x501,
+0x501,0x501,0x501,0x96,0x501,0x501,0x501,0x501,0x501,0x96,0x501,0x96,0x501,0x501,0x96,0x501,
+0x501,0x96,0x501,0x501,0x501,0x501,0x501,0x501,0x501,0x501,0x501,0x504,0x51c,0x516,0x51c,0x516,
+0x519,0x51f,0x51c,0x516,0x519,0x51f,0x51c,0x516,0x519,0x51f,0x51c,0x516,0x519,0x51f,0x51c,0x516,
+0x519,0x51f,0x51c,0x516,0x519,0x51f,0x51c,0x516,0x519,0x51f,0x51c,0x516,0x519,0x51f,0x51c,0x516,
+0x51c,0x516,0x51c,0x516,0x51c,0x516,0x51c,0x516,0x51c,0x516,0x51c,0x516,0x519,0x51f,0x51c,0x516,
+0x519,0x51f,0x51c,0x516,0x519,0x51f,0x51c,0x516,0x519,0x51f,0x51c,0x516,0x51c,0x516,0x519,0x51f,
+0x51c,0x516,0x51c,0x516,0x519,0x51f,0x51c,0x516,0x519,0x51f,0x51c,0x516,0x51c,0x516,0x99,0x99,
+0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+0x99,0x99,0x99,0x51c,0x516,0x519,0x51f,0x51c,0x516,0x51c,0x516,0x51c,0x516,0x51c,0x51c,0x516,
+0x51c,0x516,0x51c,0x516,0x51c,0x516,0x519,0x51f,0x519,0x51f,0x51c,0x516,0x51c,0x516,0x51c,0x516,
+0x51c,0x516,0x51c,0x516,0x51c,0x516,0x51c,0x516,0x519,0x51c,0x516,0x519,0x51c,0x516,0x519,0x51f,
+0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,
+0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,
+0x51c,0x51c,0x513,0x513,0x513,0x513,0x513,0x513,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,
+0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,
+0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,
+0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,
+0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x51f,0x51f,0x51f,0x51f,0x51f,
+0x51f,0x51f,0x51f,0x51f,0x51f,0x51f,0x51f,0x51f,0x51f,0x51f,0x51f,0x51f,0x51f,0x51f,0x51f,0x51f,
+0x51f,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,
+0x51c,0x51c,0x51c,0x51c,0x51c,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,
+0x516,0x516,0x516,0x516,0x516,0x519,0x519,0x519,0x519,0x519,0x519,0x519,0x51f,0x51f,0x51f,0x51f,
+0x51f,0x51f,0x51f,0x51f,0x516,0x51c,0x510,0x50d,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,
+0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x519,0x516,0x519,0x519,0x519,0x519,0x519,0x519,
+0x516,0x519,0x516,0x516,0x519,0x519,0x516,0x516,0x519,0x519,0x516,0x519,0x516,0x519,0x516,0x516,
+0x519,0x516,0x516,0x519,0x516,0x519,0x516,0x516,0x519,0x516,0x519,0x519,0x516,0x516,0x516,0x519,
+0x516,0x516,0x516,0x516,0x516,0x519,0x516,0x516,0x516,0x516,0x516,0x519,0x516,0x516,0x519,0x516,
+0x519,0x519,0x519,0x516,0x519,0x519,0x519,0x519,0x99,0x99,0x519,0x519,0x519,0x519,0x516,0x516,
+0x519,0x516,0x516,0x516,0x516,0x519,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,
+0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x519,0x519,0x516,0x516,
+0x519,0x516,0x519,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x516,0x519,0x519,0x519,0x516,0x516,
+0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x99,0x9cc,0x9cc,0x9cc,0x9cc,0x9cc,0x9cc,0x9cc,0x9cc,
+0x9cc,0x9cc,0x9cc,0x9cc,0x9cc,0x9cc,0x9cc,0x9cc,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,0x51c,
+0x51c,0x51c,0x513,0x513,0xa7a,0xb6a,0x99,0x99,0xacb,0xacb,0xacb,0xacb,0xacb,0xacb,0xacb,0xacb,
+0xacb,0xacb,0xacb,0xacb,0xacb,0xacb,0xacb,0xacb,0xd1d,0xd0e,0xd08,0xd1a,0xd17,0xd11,0xd11,0xd20,
+0xd0b,0xd14,0x11d,0x11d,0x11d,0x11d,0x11d,0x11d,0x522,0x522,0x522,0x522,0xe46,0xe46,0xe46,0x9c,
+0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x9c,0x7b3,0x7b9,0x7b9,0x7c5,0x7c5,0x7b6,0x7ad,0x7b6,
+0x7ad,0x7b6,0x7ad,0x7b6,0x7ad,0x7b6,0x7ad,0x7b6,0x7ad,0x7bf,0x7bc,0x7bf,0x7bc,0xafe,0xafe,0xbee,
+0xbeb,0x7b0,0x7b0,0x7b0,0x7b0,0x7c2,0x7c2,0x7c2,0x7da,0x7dd,0x7ec,0x9f,0x7e0,0x7e3,0x7ef,0x7ef,
+0x7d7,0x7ce,0x7c8,0x7ce,0x7c8,0x7ce,0x7c8,0x7cb,0x7cb,0x7e6,0x7e6,0x7e9,0x7e6,0x7e6,0x7e6,0x9f,
+0x7e6,0x7d4,0x7d1,0x7cb,0x9f,0x9f,0x9f,0x9f,0x528,0x534,0x528,0xa7d,0x528,0xa2,0x528,0x534,
+0x528,0x534,0x528,0x534,0x528,0x534,0x528,0x534,0x531,0x531,0x52b,0x531,0x52b,0x531,0x52b,0x531,
+0x52b,0x531,0x52b,0x52e,0x534,0x531,0x52b,0x531,0x52b,0x52e,0x534,0x531,0x52b,0x531,0x52b,0x52e,
+0x534,0x531,0x52b,0x52e,0x534,0x531,0x52b,0x52e,0x534,0x531,0x52b,0x531,0x52b,0x531,0x52b,0x531,
+0x52b,0x531,0x52b,0x52e,0x534,0x531,0x52b,0x52e,0x534,0x531,0x52b,0x52e,0x534,0x531,0x52b,0x52e,
+0x534,0x531,0x52b,0x52e,0x534,0x531,0x52b,0x52e,0x534,0x531,0x52b,0x52e,0x534,0x531,0x52b,0x52e,
+0x534,0x531,0x52b,0x52e,0x534,0x531,0x52b,0x531,0x52b,0x531,0x52b,0x52e,0x534,0x531,0x52b,0x531,
+0x52b,0x531,0x52b,0x531,0x52b,0xa2,0xa2,0x525,0xa8,0x6a5,0x684,0x675,0x67e,0x67b,0x675,0x687,
+0x678,0x672,0x675,0x693,0x68a,0x681,0x6a2,0x675,0x69f,0x69f,0x69f,0x69f,0x69f,0x69f,0x69f,0x69f,
+0x69f,0x69f,0x690,0x68d,0x693,0x693,0x693,0x6a5,0x675,0x6b1,0x6b1,0x6b1,0x6b1,0x6b1,0x6b1,0x6ab,
+0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,0x6ab,
+0x6ab,0x6ab,0x6ab,0x678,0x693,0x672,0x699,0x69c,0x696,0x6ae,0x6ae,0x6ae,0x6ae,0x6ae,0x6ae,0x6a8,
+0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,0x6a8,
+0x6a8,0x6a8,0x6a8,0x678,0x693,0x672,0x693,0xad1,0xace,0x660,0x654,0x651,0x657,0x64e,0x669,0x66c,
+0x66c,0x66c,0x66c,0x66c,0x66c,0x66c,0x66c,0x66c,0x65d,0x669,0x669,0x669,0x669,0x669,0x669,0x669,
+0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,
+0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x669,0x648,0x648,0x666,0x663,0x663,0x663,
+0x663,0x663,0x663,0x663,0x663,0x663,0x663,0x663,0x663,0x663,0x663,0x663,0x663,0x663,0x663,0x663,
+0x663,0x663,0x663,0x663,0x663,0x663,0x663,0x663,0x663,0x663,0x663,0xa8,0xa8,0xa8,0x663,0x663,
+0x663,0x663,0x663,0x663,0xa8,0xa8,0x663,0x663,0x663,0x663,0x663,0x663,0xa8,0xa8,0x663,0x663,
+0x663,0x663,0x663,0x663,0xa8,0xa8,0x663,0x663,0x663,0xa8,0xa8,0xa8,0x67b,0x67e,0x693,0x696,
+0x675,0x67e,0x67e,0xa8,0x64b,0x65a,0x65a,0x65a,0x65a,0x64b,0x64b,0xa8,0xa5,0xa5,0xa5,0xa5,
+0xa5,0xa5,0xa5,0xa5,0xa5,0x996,0x996,0x996,0x855,0x642,0x537,0x537,0xbaf,0xbaf,0xbaf,0xbaf,
+0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xd8,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,
+0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xd8,
+0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,
+0xbaf,0xbaf,0xbaf,0xd8,0xbaf,0xbaf,0xd8,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,
+0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xd8,0xd8,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,
+0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xbaf,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,
+0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,
+0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,
+0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,
+0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xbb2,0xdb,0xdb,0xdb,0xdb,0xdb,
+0xbb8,0xbb8,0xbb8,0xde,0xde,0xde,0xde,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,
+0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,
+0xde,0xde,0xde,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xbb5,0xc6c,0xc6c,0xc6c,0xc6c,
+0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,
+0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc6c,0xc69,0xc69,0xc69,
+0xc69,0xc69,0xc69,0xc69,0xc69,0xc69,0xc69,0xc69,0xc69,0xc69,0xc69,0xf0,0xf0,0xf0,0xf0,0xf0,
+0xf48,0xf48,0xf48,0xf48,0xf48,0xf48,0xf48,0xf48,0xf48,0xf48,0xf48,0xf48,0x14d,0x14d,0x14d,0x14d,
+0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,
+0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0x14d,0xf4b,0xf4b,0xf4b,0xf4b,
+0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,
+0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4b,0xf4e,0x150,0x150,0xf51,0xf51,0xf51,0xf51,
+0xf51,0xf51,0xf51,0xf51,0xf51,0xf51,0xf51,0xf51,0xf51,0xf51,0xf51,0xf51,0xf51,0xf51,0xf51,0xf51,
+0xf51,0xf51,0xf51,0xf51,0xf51,0xf51,0xf51,0xf51,0xf51,0x153,0x153,0x153,0xf54,0xf54,0xf54,0xf54,
+0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,
+0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0xf54,0x156,0x156,0x156,
+0x156,0x156,0x156,0x156,0x156,0x156,0x156,0x156,0x156,0x156,0x156,0x156,0x9d2,0x9d2,0x9d2,0x9d2,
+0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,
+0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0x9d2,0xab,0x9cf,0x9cf,0x9cf,0x9cf,
+0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0xab,0x9d5,0x9d5,0x9d5,0x9d5,
+0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0x9d5,0xae,
+0xae,0xae,0xae,0xae,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,
+0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,0xbbe,
+0xbbe,0xbbe,0xe1,0xbbb,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,
+0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,
+0xcc6,0xcc6,0xcc6,0xcc6,0x111,0x111,0x111,0x111,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,
+0xcc3,0xcc6,0xcc6,0xcc6,0xcc6,0xcc6,0x111,0x111,0x111,0x111,0x111,0x111,0x111,0x111,0x111,0x111,
+0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,
+0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,0x9db,
+0x9db,0x9db,0xb70,0xb70,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,
+0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0x9d8,0xb6d,0xb6d,
+0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,
+0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,0xbc1,
+0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,
+0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xbc7,0xe4,0xe4,
+0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,0xbc4,0xe4,0xe4,0xe4,0xe4,0xe4,0xe4,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xe7,0xe7,0xbca,0xe7,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,
+0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,0xbca,
+0xbca,0xbca,0xe7,0xbca,0xbca,0xe7,0xe7,0xe7,0xbca,0xe7,0xe7,0xbca,0x1083,0x1083,0x1083,0x1083,
+0x1083,0x1083,0x1083,0x1083,0x1083,0x1083,0x1083,0x1083,0x1083,0x1083,0x1083,0x1083,0x1083,0x1083,0x1083,0x1083,
+0x1083,0x1083,0x189,0x1080,0x107d,0x107d,0x107d,0x107d,0x107d,0x107d,0x107d,0x107d,0xdbf,0xdbf,0xdbf,0xdbf,
+0xdbf,0xdbf,0xdbf,0xdbf,0xdbf,0xdbf,0xdbf,0xdbf,0xdbf,0xdbf,0xdbf,0xdbf,0xdbf,0xdbf,0xdbf,0xdbf,
+0xdbf,0xdbf,0xdb9,0xdb9,0xdb9,0xdb9,0xfbd,0xfbd,0x12c,0x12c,0x12c,0xdbc,0xf5a,0xf5a,0xf5a,0xf5a,
+0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,
+0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,0xf5a,0x159,0x159,0x159,0x159,0x159,0xf57,0xcb1,0xca5,0xca5,0xca5,
+0x10b,0xca5,0xca5,0x10b,0x10b,0x10b,0x10b,0x10b,0xca5,0xca5,0xca5,0xca5,0xcb1,0xcb1,0xcb1,0xcb1,
+0x10b,0xcb1,0xcb1,0xcb1,0x10b,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,
+0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0xcb1,0x10b,0x10b,0x10b,0x10b,
+0xca2,0xca2,0xca2,0x10b,0x10b,0x10b,0x10b,0xca8,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,0xcab,
+0x10b,0x10b,0x10b,0x10b,0x10b,0x10b,0x10b,0x10b,0xcae,0xcae,0xcae,0xcae,0xcae,0xcae,0xcae,0xcae,
+0xcab,0x10b,0x10b,0x10b,0x10b,0x10b,0x10b,0x10b,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,
+0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,0x1089,
+0x1089,0x1089,0x1089,0x1089,0x1089,0x1086,0x1086,0x1086,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,
+0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,
+0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x1092,0x18c,0x18c,0x18c,0x108c,0x108f,0x108f,
+0x108f,0x108f,0x108f,0x108f,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,
+0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x1098,0x18f,0x18f,0x1095,0x1095,0x1095,0x1095,
+0x1095,0x1095,0x1095,0x1095,0x109e,0x109e,0x109e,0x109e,0x109e,0x109e,0x109e,0x109e,0x109e,0x109e,0x109e,0x109e,
+0x109e,0x109e,0x109e,0x109e,0x109e,0x109e,0x109e,0x192,0x192,0x192,0x192,0x192,0x109b,0x109b,0x109b,0x109b,
+0x109b,0x109b,0x109b,0x109b,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,
+0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,
+0x10a1,0x10a1,0x10a1,0x10a1,0x10a1,0x195,0x195,0x195,0x195,0x195,0x195,0x195,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0x10a4,0x10a4,0x10a4,0x10a4,
+0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,
+0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x10a4,0x198,0x10aa,0x10aa,0x10b9,0x10bc,
+0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,
+0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bf,0x10bc,0x10bf,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,
+0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bc,0x10bf,0x10bc,0x10bc,0x10bc,0x10bc,0x10b9,0x10b9,0x10b9,0x10ad,
+0x10ad,0x10ad,0x10ad,0x10b9,0x10b9,0x10b3,0x10b0,0x10b6,0x10b6,0x10a7,0x10c2,0x10c2,0x10c2,0x10c2,0x19b,0x19b,
+0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0x19b,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xdc2,0xdc2,0xdc2,0xdc2,
+0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,
+0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0xdc2,0x12f,
+0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,
+0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,0x12f,
+0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,
+0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,0xdc8,
+0xdc8,0xdc8,0xdc8,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,
+0xdc5,0xdc5,0xdc5,0xdc5,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,0x132,
+0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,
+0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,
+0x10cb,0x10cb,0x10cb,0x10c8,0x10c8,0x10c8,0x10c5,0x10c5,0x10c5,0x10c5,0x10c8,0x10c5,0x10c5,0x10c5,0x10cb,0x10c8,
+0x10cb,0x10c8,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,
+0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10cb,0x10c8,0x10c8,
+0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x10c5,0x19e,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,
+0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,0x9de,
+0x9de,0x9de,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0x9ea,0x9ea,0x9ea,0x9ea,
+0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,
+0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0xb4,
+0xb4,0xe49,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,
+0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,
+0x9ea,0x9ea,0x9ed,0x9ed,0x9ed,0x9ed,0x9ed,0x9ed,0x9ed,0x9e4,0x9f0,0x9f6,0x9f6,0x9f6,0x9ea,0x9ea,
+0x9ea,0x9f3,0x9e7,0x9e7,0x9e7,0x9e7,0x9e7,0x9e1,0x9e1,0x9e1,0x9e1,0x9e1,0x9e1,0x9e1,0x9e1,0x9f6,
+0x9f6,0x9f6,0x9f6,0x9f6,0x9f6,0x9f6,0x9f6,0x9ea,0x9ea,0x9f6,0x9f6,0x9f6,0x9f6,0x9f6,0x9f6,0x9f6,
+0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,
+0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9f6,0x9f6,0x9f6,0x9f6,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,
+0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ed,0x9ed,0x9ed,0x9ed,0x9ed,0x9ed,0x9ea,0x9ea,0x9ea,
+0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,
+0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0x9ea,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,
+0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,
+0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xc66,0xc66,0xc66,0xc66,
+0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,
+0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc66,0xc63,0xc63,
+0xc63,0xc66,0xed,0xed,0xed,0xed,0xed,0xed,0xed,0xed,0xed,0xed,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0xbcd,0xbcd,0xbcd,0xbcd,
+0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,
+0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xbcd,0xea,
+0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,
+0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0xdcb,0x135,0x135,0x135,0x135,0x135,0x135,
+0x135,0x135,0x135,0x135,0x135,0x135,0x135,0x135,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
+0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
+0xa02,0xa02,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,
+0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
+0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0xb7,0x9ff,0x9ff,
+0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
+0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
+0xa02,0xa02,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,
+0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0xa02,0xb7,0xa02,0xa02,
+0xb7,0xb7,0xa02,0xb7,0xb7,0xa02,0xa02,0xb7,0xb7,0xa02,0xa02,0xa02,0xa02,0xb7,0xa02,0xa02,
+0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0x9ff,0x9ff,0x9ff,0x9ff,0xb7,0x9ff,0xb7,0x9ff,0x9ff,0x9ff,
+0x9ff,0xb73,0x9ff,0x9ff,0xb7,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,
+0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
+0x9ff,0x9ff,0x9ff,0x9ff,0xa02,0xa02,0xb7,0xa02,0xa02,0xa02,0xa02,0xb7,0xb7,0xa02,0xa02,0xa02,
+0xa02,0xa02,0xa02,0xa02,0xa02,0xb7,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xb7,0x9ff,0x9ff,
+0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,
+0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0xa02,0xa02,0xb7,0xa02,0xa02,0xa02,0xa02,0xb7,
+0xa02,0xa02,0xa02,0xa02,0xa02,0xb7,0xa02,0xb7,0xb7,0xb7,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
+0xa02,0xb7,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,
+0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
+0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,
+0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,
+0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
+0x9ff,0x9ff,0x9ff,0x9ff,0xc4e,0xc4e,0xb7,0xb7,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
+0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
+0xa02,0x9f9,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,
+0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9f9,0x9ff,0x9ff,0x9ff,0x9ff,
+0x9ff,0x9ff,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
+0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0x9f9,0x9ff,0x9ff,0x9ff,0x9ff,
+0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,
+0x9ff,0x9f9,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0x9ff,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,
+0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0xa02,0x9ff,0x9ff,0x9ff,0x9f9,0x9ff,0x9ff,0x9ff,0x9ff,
+0x9ff,0x9ff,0xd56,0xd53,0xb7,0xb7,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,
+0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,
+0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0x9fc,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,
+0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,
+0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0xf5d,0x15c,0x15c,0x15c,0x15c,0xf60,0xf60,0xf60,0xf60,
+0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,
+0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0xf60,0x15f,0x15f,0x15f,0x15f,
+0x15f,0x15f,0x15f,0x15f,0x15f,0x15f,0x15f,0x15f,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,
+0x10e3,0x10e3,0x10e3,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,
+0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e3,0x10e6,0x10e6,0x10e6,0x10ce,0x1a1,
+0x1a1,0x10e9,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x10e9,0x1a1,0x10e9,
+0x1a1,0x1a1,0x10e9,0x1a1,0x1a1,0x1a1,0x10e9,0x1a1,0x1a1,0x1a1,0x10e9,0x10e9,0x10e9,0x10e9,0x10e9,0x1a1,
+0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x10e0,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x10e0,
+0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,
+0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x10e0,0x1a1,0x10e0,0x10e0,0x1a1,0x1a1,0x10e0,
+0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x10e0,0x10e0,0x10e0,0x10e0,0x1a1,0x1a1,
+0x10e9,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,
+0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,0x1a1,
+0x1a1,0x1a1,0x1a1,0x1a1,0x110d,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,
+0x1a4,0x1a4,0x1a4,0x1a4,0x110a,0x110a,0x110a,0x110a,0x110a,0x110a,0x110a,0x110a,0x110a,0x110a,0x110a,0x110a,
+0x110a,0x110a,0x110a,0x110a,0x110a,0x110a,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,
+0x1a4,0x1a4,0x1a4,0x1a4,0x1107,0x1107,0x1107,0x1107,0x1107,0x1107,0x1107,0x1107,0x1107,0x1a4,0x1a4,0x1a4,
+0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,
+0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,0x1a4,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x7f2,0x7f2,
+0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,
+0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,0xa08,
+0xa08,0xa08,0xa08,0x1b3,0x1b3,0x1b3,0x1b3,0x1b3,0x1b3,0x1b3,0x1b3,0x1b3,0x1a7,0x1a7,0x1a7,0x1a7,
+0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,
+0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1110,0x1110,0x1110,0x1110,
+0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,
+0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1110,0x1b9,0x1b9,0x1b9,
+0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0x1b9,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,
+0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,
+0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0xa0b,0x1b6,0x1b6,0x1a7,0x1a7,0x1a7,0x1a7,
+0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,
+0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x1a7,0x7f2,0x7f2,0xba,0xa05,0xba,0xba,
+0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,
+0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xba,0xa05,0xa05,0xa05,0xa05,
+0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,
+0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,0xa05,3,3,3,3,
+3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+3,3,3,3,3,3,3,3,3,3,3,3,0xbdc,0xbdc,0xbdc,0xbdc,
+0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,
+0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,0xbdc,3,3,3,3,
+3,3,3,3,3,3,3,3,3,3,3,3,0x849,0x849,0x849,0x849,
+0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,
+0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x849,0x843,0x843,
+0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,
+0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,0x84c,
+0x84c,0x84c,0x846,0x846,0,0,0,0
+};
+
+static const UTrie2 propsVectorsTrie={
+    propsVectorsTrie_index,
+    propsVectorsTrie_index+3692,
+    NULL,
+    3692,
+    16156,
+    0xa40,
+    0xeec,
+    0x0,
+    0x0,
+    0x110000,
+    0x4d84,
+    NULL, 0, FALSE, FALSE, 0, NULL
+};
+
+static const uint32_t propsVectors[4371]={
+0x67,0,0,0x67,0x80000,0,0x867,0,0,0xa67,0,0,0xb67,0,0,0xc67,
+0,0,0xd67,0,0,0xe67,0,0,0xf67,0,0,0x1067,0,0,0x1167,0,
+0,0x1267,0,0,0x1367,0,0,0x1467,0,0,0x1567,0,0,0x1667,0,0,
+0x1767,0,0,0x1867,0,0,0x1967,0,0,0x1a67,0,0,0x1b67,0,0,0x1d67,
+0,0,0x1f67,0,0,0x2067,0,0,0x2267,0,0,0x2367,0,0,0x2467,0,
+0,0x2567,0,0,0x2767,0,0,0x2867,0x80000,0,0x2967,0,0,0x2a67,0,0,
+0x2b67,0,0,0x2d67,0,0,0x3067,0x20000000,0,0x3167,0x20000000,0,0x3267,0x20000000,0,0x3767,
+0x20000000,0,0x3867,0x20000000,0,0x3a67,0,0,0x3b67,0,0,0x3c67,0,0,0x3e67,0,
+0,0x4067,0,0,0x4167,0,0,0x4367,0,0,0x4467,0,0,0x4867,0,0,
+0x4967,0,0,0x4a67,0,0,0x5067,0,0,0x5167,0,0,0x5267,0,0,0x5467,
+0,0,0x5567,0,0,0x5667,0x80000,0,0x5767,0,0,0x5867,0,0,0x5967,0,
+0,0x5b67,0,0,0x5c67,0,0,0x5d67,0,0,0x6067,0x80000,0,0x6167,0,0,
+0x6267,0,0,0x6367,0,0,0x6467,0,0,0x6567,0,0,0x6667,0x20000000,0,0x6f67,
+0,0,0x7067,0,0,0x7367,0x20000000,0,0x7567,0,0,0x7667,0,0,0x7767,0,
+0,0x7867,0,0,0x7a67,0,0,0x7b67,0,0,0x7c67,0,0,0x7e67,0,0,
+0x7f67,0,0,0x8167,0,0,0x8267,0,0,0x8367,0,0,0x8467,0,0,0x8567,
+0,0,0x8667,0,0,0x8767,0,0,0x8867,0,0,0x8967,0,0,0x8b67,0,
+0,0x8c67,0,0,0x8e67,0x20000000,0,0x8f67,0,0,0x9067,0,0,0x9167,0,0,
+0x9267,0,0,0x9367,0,0,0x9567,0,0,0x9667,0,0,0x9767,0,0,0x9867,
+0,0,0x9967,0,0,0x9a67,0,0,0x9b67,0,0,0x9c67,0,0,0x9f67,0,
+0,0xa067,0,0,0xa167,0,0,0xa367,0,0,0xa467,0,0,0xa567,0,0,
+0xa667,0,0,0xa767,0,0,0xa867,0,0,0xa967,0,0,0xaa67,0,0,0xab67,
+0,0,0xac67,0,0,0xad67,0,0,0xae67,0,0,0xaf67,0,0,0xb167,0,
+0,0xb267,0,0,0xb367,0,0,0xb467,0,0,0xb567,0,0,0xb667,0,0,
+0xb767,0,0,0xb867,0,0,0xb967,0,0,0xba67,0,0,0xbc67,0,0,0xbd67,
+0,0,0xbe67,0,0,0xbf67,0,0,0xc067,0,0,0xc167,0,0,0xc267,0,
+0,0xc367,0,0,0xc467,0,0,0xa0067,0,0xe00000,0xa4667,0,0xe00000,0xa4767,0,0xe00000,
+0xa4f67,0,0xe00000,0xa5e67,0,0xe00000,0xa5f67,0,0xe00000,0xac567,0,0xe00000,0x11000100,0,0x900020,0x11000100,
+0x40000001,0x440020,0x11000100,0x40000001,0x643020,0x11000100,0x40000001,0xa5a040,0x11000100,0x40000001,0x116a8a0,0x11000200,0,0x900020,0x11000200,0x4000001,
+0xc4000b,0x11000200,0x7c00100,0x220402,0x11000200,0x24000000,0x200000,0x11000200,0x24000008,0x1710000,0x11000200,0x40000001,0x1d3b020,0x11000219,0x7c00100,0x220401,
+0x11000219,0x7c00100,0x250401,0x11000319,0x7c00100,0x220401,0x11000319,0x7c00100,0x220402,0x11000319,0x7c00100,0x250400,0x11000319,0x7c00100,0x250401,0x11000419,
+0x7c00100,0x220400,0x11000419,0x7c00100,0x220401,0x11000419,0x7c00100,0x220402,0x11000419,0x7c00100,0x230400,0x11000419,0x7c00100,0x250400,0x11000419,0x7c00100,
+0x250401,0x11000419,0x7c00100,0x250402,0x11000519,0x7c00100,0x220400,0x11000519,0x7c00100,0x230400,0x11000600,0x4000400,0x200000,0x11000600,0x4000400,0x200002,
+0x11000600,0x7c00500,0x220400,0x11000600,0x7c00500,0x230400,0x11000600,0x7c00500,0x530400,0x11000600,0x7c00d00,0x230400,0x11000619,0x7c00500,0x22040f,0x11000800,
+0x4000010,0x1001401,0x11000800,0x4000400,0x200001,0x11000800,0x6800010,0x201001,0x11000800,0x7c00500,0x230401,0x11000807,0x7c00100,0x220400,0x11000807,0x7c00100,
+0x250400,0x1100080e,0x4000400,0x200000,0x1100080e,0x4000400,0x200002,0x1100080e,0x7000500,0x220402,0x1100080e,0x7c00100,0x220400,0x1100080e,0x7c00100,0x220401,
+0x1100080e,0x7c00100,0x220402,0x1100080e,0x7c00100,0x250400,0x1100080e,0x7c00100,0x250401,0x1100080e,0x7c00120,0x220402,0x1100080e,0x7c00120,0x250402,0x11000901,
+0x2802400,0x962460,0x11000908,0x2802400,0x962460,0x11000908,0x4000000,0x200000,0x11000908,0x7c00100,0x220400,0x11000908,0x7c00100,0x220401,0x11000908,0x7c00100,
+0x250400,0x11000908,0x7c00100,0x250401,0x11000a00,0xc000010,0x1049400,0x11000a03,0x4000000,0x200000,0x11000a03,0x4000000,0x270000,0x11000a03,0x7c00100,0x220400,
+0x11000a03,0x7c00100,0x220402,0x11000a03,0x7c00100,0x250400,0x11000a03,0x7c00500,0x230400,0x11000a03,0xc000000,0x248000,0x11000b13,0x2802500,0x962460,0x11000b13,
+0x4000000,0x200000,0x11000b13,0x4000000,0x201000,0x11000b13,0x4000000,0x230400,0x11000b13,0x4000002,0x400000,0x11000b13,0x4000010,0x200000,0x11000b13,0x7c00100,
+0x230400,0x11000c00,0,0x218820,0x11000c00,0x4000010,0xb00000,0x11000c00,0x4000010,0x1071400,0x11000c00,0x6800000,0x1329800,0x11000c00,0x7c00900,0x230400,
+0x11000c00,0xc000010,0xb48000,0x11000c01,0x2802100,0x962460,0x11000c01,0x2802500,0x962460,0x11000c02,0x2000,0x962460,0x11000c02,0x2802100,0x962460,0x11000c02,
+0x2802400,0x962460,0x11000c02,0x4000000,0x200000,0x11000c02,0x4000000,0x1329400,0x11000c02,0x4000000,0x1329800,0x11000c02,0x4000000,0x1500000,0x11000c02,0x6800000,
+0x1329800,0x11000c02,0x7c00100,0x230400,0x11000c02,0x7c00100,0x230401,0x11000c02,0x7c00100,0x230402,0x11000c02,0x7c00500,0x230400,0x11000c02,0xc000010,0xb48000,
+0x11000f00,0x4000000,0x200000,0x11000f00,0xc000010,0x448000,0x11000f01,0x2802400,0x962460,0x11000f0a,0x2802100,0x962460,0x11000f0a,0x2802400,0x962460,0x11000f0a,
+0x2806400,0x962460,0x11000f0a,0x6800000,0x1329800,0x11000f0a,0x6800100,0x962540,0x11000f0a,0x7c00100,0x230400,0x11000f0a,0x7c00100,0x230401,0x11001004,0x2802100,
+0x962460,0x11001004,0x2802400,0x962460,0x11001004,0x2806400,0x962460,0x11001004,0x4000000,0x200000,0x11001004,0x4000000,0x1500000,0x11001004,0x6800000,0x1329800,
+0x11001004,0x6800100,0x962540,0x11001004,0x6800100,0x962541,0x11001004,0x7c00100,0x230400,0x11001004,0x7c00100,0x230401,0x11001110,0x2802100,0x962460,0x11001110,
+0x2802400,0x962460,0x11001110,0x2806400,0x962460,0x11001110,0x6800000,0x1329800,0x11001110,0x6800100,0x962540,0x11001110,0x7c00100,0x230400,0x11001110,0x7c00100,
+0x230401,0x1100120f,0x2802100,0x962460,0x1100120f,0x2802400,0x962460,0x1100120f,0x2806400,0x962460,0x1100120f,0x6800000,0x1329800,0x1100120f,0x6800100,0x962540,
+0x1100120f,0x7c00100,0x230400,0x1100131f,0x2802100,0x962460,0x1100131f,0x2802400,0x962460,0x1100131f,0x2806400,0x962460,0x1100131f,0x4000000,0x200000,0x1100131f,
+0x6800000,0x1329800,0x1100131f,0x6800100,0x962540,0x1100131f,0x6800100,0x962541,0x1100131f,0x7c00100,0x230400,0x1100131f,0x7c00100,0x230401,0x11001423,0x2802100,
+0x962460,0x11001423,0x2806400,0x962460,0x11001423,0x4000000,0x200000,0x11001423,0x6800000,0x1329800,0x11001423,0x6800100,0x962540,0x11001423,0x6800100,0x962541,
+0x11001423,0x7c00100,0x230400,0x11001423,0x7c00100,0x230401,0x11001524,0x2802100,0x962460,0x11001524,0x2802100,0x962461,0x11001524,0x2806400,0x962460,0x11001524,
+0x6800000,0x1329800,0x11001524,0x6800100,0x962540,0x11001524,0x7c00100,0x230400,0x11001615,0x2802100,0x962460,0x11001615,0x2806400,0x962460,0x11001615,0x6800000,
+0x1329800,0x11001615,0x6800100,0x962540,0x11001615,0x6800100,0x962541,0x11001615,0x7c00100,0x230400,0x1100171a,0x2802100,0x962460,0x1100171a,0x2806400,0x962460,
+0x1100171a,0x6800000,0x1329800,0x1100171a,0x6800100,0x962540,0x1100171a,0x6800100,0x962541,0x1100171a,0x7c00100,0x230400,0x11001900,0x4000000,0x1600000,0x11001926,
+0x2802100,0x1862460,0x11001926,0x2802400,0x1862460,0x11001926,0x2806100,0x1862460,0x11001926,0x4000000,0x200000,0x11001926,0x4000010,0x400000,0x11001926,0x6800000,
+0x1329800,0x11001926,0x7800100,0x1830062,0x11001926,0x7c00100,0x1830000,0x11001926,0x7c00100,0x1830060,0x11001926,0x7c00900,0x1830000,0x11001926,0x7e00100,0x1830160,
+0x11001a18,0x2802100,0x1862460,0x11001a18,0x2802400,0x1862460,0x11001a18,0x6800000,0x1329800,0x11001a18,0x7800100,0x1830062,0x11001a18,0x7c00100,0x1830000,0x11001a18,
+0x7c00100,0x1830002,0x11001a18,0x7c00100,0x1830060,0x11001a18,0x7c00900,0x1830000,0x11001a18,0x7e00100,0x1830160,0x11001d00,0x4000000,0x200000,0x11001d0c,0x7c00100,
+0x230400,0x11001d0c,0x7c00100,0x250400,0x11001e12,0x7c00100,0x2230500,0x11001e12,0x7c00100,0x2330520,0x11001e12,0x7c80100,0x2330520,0x11002619,0x7c00100,0x220401,
+0x11002619,0x7c00100,0x220402,0x11002619,0x7c00100,0x250401,0x1100270e,0x4000400,0x200001,0x1100270e,0x4000400,0x200002,0x1100270e,0x4000400,0x500001,0x1100270e,
+0x7c00100,0x220401,0x1100270e,0x7c00100,0x250401,0x11002800,0x80000,0x918820,0x11002800,0x80000,0x1c18020,0x11002800,0x180000,0x918820,0x11002800,0x4000001,
+0x440001,0x11002800,0x4000001,0x440002,0x11002800,0x4000001,0xc4000b,0x11002800,0x6800000,0x201c00,0x11002800,0x6800020,0x201c00,0x11002800,0x24000000,0x200000,
+0x11002800,0x24000000,0x200002,0x11002800,0x24000000,0x810000,0x11002800,0x24000000,0x1410000,0x11002800,0x24000000,0x1500000,0x11002800,0x24000000,0x1500002,0x11002800,
+0x24000002,0x400000,0x11002800,0x24000006,0xc0000b,0x11002800,0x24000008,0x1410000,0x11002800,0x24000008,0x1710000,0x11002800,0x24000020,0x1001400,0x11002800,0x24000020,
+0x1500002,0x11002800,0x2c000010,0x1248000,0x11002800,0x2c000010,0x1248002,0x11002800,0x40000001,0x63b020,0x11002800,0x40080000,0x918820,0x11002801,0x82000,0x962460,
+0x11002900,0x4000000,0x20000e,0x11002900,0x4000000,0x20000f,0x11002900,0x4000020,0x20000e,0x11002900,0x4000020,0x20000f,0x11002900,0x4000020,0x81000e,0x11002900,
+0x4000020,0x81000f,0x11002900,0x4000020,0x141000e,0x11002900,0x4000020,0x141000f,0x11002900,0x4000022,0x20000e,0x11002900,0x4000022,0x20000f,0x11002a00,0x4000000,
+0x1500000,0x11002a00,0x4000000,0x1600000,0x11002a00,0x4000000,0x1600002,0x11002b01,0x2000,0x962460,0x11002b01,0x2802020,0x962460,0x11002c00,0x4000000,0x200000,
+0x11002c00,0x4000000,0x200002,0x11002c00,0x4000000,0x20000f,0x11002c00,0x4000020,0x200000,0x11002c00,0x7c00000,0x200000,0x11002c00,0x7c00100,0x250402,0x11002c00,
+0x7c00120,0x220405,0x11002c00,0x7c00120,0x230402,0x11002c00,0x7c00120,0x250405,0x11002c19,0x7c00100,0x250400,0x11002c19,0x7c00100,0x250401,0x11002d00,0x4000000,
+0x100006,0x11002d00,0x4000000,0x200006,0x11002d19,0x7c00100,0x220402,0x11002d19,0x7c00100,0x230400,0x11002d19,0x7c00100,0x250402,0x11002e00,0x24000000,0x200000,
+0x11002e00,0x24000020,0x200000,0x11002e00,0x24000020,0x200001,0x11002f00,0x24000020,0x200000,0x11002f00,0x24000020,0x200001,0x11002f00,0x24000020,0x200002,0x11002f00,
+0x24000020,0x1600000,0x11002f00,0x24000022,0x1600000,0x11003000,0x24000000,0x200000,0x11003000,0x24000020,0x200000,0x11003100,0x24000000,0x200000,0x11003200,0x24000000,
+0x200000,0x11003300,0x4000000,0x100003,0x11003400,0x24000000,0x100000,0x11003400,0x24000000,0x200000,0x11003500,0x24000000,0x200000,0x11003600,0x24000000,0x200000,
+0x11003600,0x24000020,0x200000,0x11003700,0x24000000,0x200000,0x11003700,0x24000020,0x200000,0x11003800,0x4000000,0x100000,0x11003800,0x24000000,0x200000,0x11003800,
+0x24000000,0xb00000,0x11003800,0x24000000,0x1710000,0x11003d00,0x4000000,0xe00000,0x11005003,0x7c00100,0x220402,0x11005013,0x2802500,0x962460,0x11005013,0x4000020,
+0x200005,0x11005013,0x7c00100,0x230401,0x11005013,0x7c00100,0x230402,0x11005013,0x7c00100,0x230405,0x11005019,0x7c00100,0x220402,0x11005100,0x24000000,0x810000,
+0x11005100,0x24000000,0x1410000,0x11005102,0x7000100,0x230408,0x11005102,0x7c00100,0x230404,0x11005102,0x7c00100,0x230407,0x11005102,0x7c00100,0x230408,0x11005102,
+0x7c00100,0x230409,0x11005201,0x2802400,0x962460,0x11005500,0x80000,0x1e18820,0x11005502,0x7000100,0x230408,0x11005502,0x7c00100,0x230404,0x11005502,0x7c00100,
+0x230407,0x11005502,0x7c00100,0x230408,0x11005502,0x7c00100,0x230409,0x11005667,0x1000,0,0x11020200,0x80004,0x418820,0x11020200,0x4000000,0x100006,
+0x11020200,0x4000000,0x10000f,0x11020200,0x4000400,0x100002,0x11020200,0x4000400,0x500002,0x11020200,0x6800c00,0x101000,0x11020200,0x24000000,0x100000,0x11020200,
+0x24000000,0x200000,0x11020200,0x24000000,0x1400000,0x11020200,0x24000000,0x1500000,0x11020200,0x24000000,0x1600000,0x11020200,0x24000020,0x100000,0x11020200,0x24000020,
+0x1600000,0x11020219,0x7c00100,0x12040f,0x11020219,0x7c00100,0x220400,0x11020219,0x7c00100,0x220401,0x11020219,0x7c00100,0x250400,0x11020319,0x7c00100,0x220400,
+0x11020319,0x7c00100,0x220401,0x11020319,0x7c00100,0x220402,0x11020319,0x7c00100,0x250400,0x11020319,0x7c00100,0x250402,0x11020319,0x7d00100,0x220402,0x11020419,
+0x7c00100,0x220401,0x11020519,0x7c00100,0x220400,0x11020600,0x4000400,0x100002,0x11020600,0x4000400,0x200000,0x11020600,0x7c00500,0x130400,0x11020600,0x7c00d00,
+0x130400,0x11020701,0x2802400,0x962460,0x11020701,0x2802400,0x962461,0x11020701,0x2802400,0xc62460,0x11020701,0x2802500,0x962460,0x1102080e,0x7c00100,0x220400,
+0x1102080e,0x7c00100,0x250400,0x11020908,0x7c00100,0x220400,0x11020908,0x7c00100,0x220401,0x11020908,0x7c00100,0x250400,0x11020908,0x7c00100,0x250401,0x11022800,
+0x24000000,0x100000,0x11022800,0x24000000,0x200000,0x11022800,0x24000000,0x200002,0x11022800,0x24000000,0x401000,0x11022800,0x24000000,0xf00002,0x11022800,0x24000000,
+0xf0ac02,0x11022800,0x24000000,0x1500000,0x11022800,0x24000002,0x100000,0x11022800,0x24000002,0x370000,0x11022800,0x24000002,0x470000,0x11022800,0x24000006,0x400000,
+0x11022800,0x24000008,0x1710000,0x11022800,0x24000008,0x1712c00,0x11022800,0x24000020,0x100000,0x11022800,0x24000020,0x1500000,0x11022800,0x24000020,0x1500002,0x11022900,
+0x4000000,0x10000e,0x11022900,0x4000000,0x10000f,0x11022919,0x7c00100,0x13040f,0x11022c00,0x4000000,0x100002,0x11022c00,0x4000000,0x10000f,0x11022c00,0x4000000,
+0x1500002,0x11022c00,0x4000000,0x1600002,0x11022c00,0x7c00120,0x120405,0x11022c0e,0x7c00100,0x250401,0x11022c19,0x7c00100,0x150401,0x11022d00,0x4000000,0x100006,
+0x11022d00,0x4000000,0x200006,0x11022d19,0x7c00100,0x120402,0x11022d19,0x7c00100,0x150402,0x11022e00,0x24000000,0x200000,0x11022e00,0x24000020,0x100000,0x11022f00,
+0x24000020,0x100000,0x11022f00,0x24000020,0x100001,0x11022f00,0x24000020,0x100002,0x11023000,0x24000000,0x100000,0x11023300,0x4000000,0x100002,0x11023300,0x4000000,
+0x100003,0x11023300,0x4000100,0x120403,0x11023300,0x4000100,0x150403,0x11023400,0x24000000,0x100000,0x11023500,0x24000000,0x100000,0x11023600,0x24000000,0x100000,
+0x11023600,0x24000020,0x100000,0x11023700,0x24000000,0x100000,0x11023700,0x24000020,0x100000,0x11023800,0x4000000,0x100000,0x11023800,0x24000000,0x200000,0x11024e67,
+0,0,0x11025600,0x4000000,0x100000,0x11042a00,0x4000000,0x1600000,0x11045700,0x3802500,0x126246a,0x11045700,0x4000000,0x20000a,0x11045700,0x4000004,
+0x120000a,0x11045700,0x4000008,0x81000a,0x11045700,0x4000008,0x141000a,0x11045700,0x4000010,0x87000a,0x11045700,0x4000020,0x20000a,0x11045700,0x7c00d00,0x1230c0a,
+0x11045700,0xc000010,0x84800a,0x11045712,0x7c00100,0x23040a,0x11045712,0x7c80100,0x23040a,0x11045716,0x7c00100,0x230c0a,0x11045716,0x7c00100,0x1230c0a,0x11063d00,
+0x4000001,0xe40011,0x11065700,0x4000000,0x810011,0x11065700,0x4000000,0xe00011,0x11065700,0x4000000,0x1410011,0x11065700,0x4000000,0x1500011,0x11065700,0x4000000,
+0x1600011,0x11065700,0x4000006,0xe70011,0x11065700,0x4000008,0xe00011,0x11065700,0x4000008,0xe02c11,0x11065700,0x4000010,0x871411,0x11065700,0x4000010,0x1201411,
+0x11065700,0x4000010,0x1271011,0x11065700,0x4000020,0xe00011,0x11065700,0x4000400,0xe00011,0x11065700,0x4000420,0xe00011,0x11065700,0x6800000,0xe01c11,0x11065700,
+0x6800040,0xe00011,0x11065700,0xc000010,0x80ac11,0x11065700,0xc000010,0xb48011,0x11065719,0x7c00100,0xe20411,0x11065719,0x7c00100,0xe50411,0x11065719,0x7c00140,
+0xe20411,0x11065719,0x7c00140,0xe50411,0x11080100,0x6800000,0x201c00,0x11080100,0x68000c0,0x1329800,0x11080100,0x24000000,0x200000,0x11080100,0x24000000,0x810000,
+0x11080100,0x24000000,0x1410000,0x11080100,0x24000000,0x1500000,0x11080100,0x24000000,0x1600000,0x11080100,0x24000000,0x1b00000,0x11080100,0x24000000,0x2410000,0x11080100,
+0x24000006,0xd70000,0x11080100,0x24000008,0x1710000,0x11080100,0x24000008,0x1712c00,0x11080100,0x24000010,0x1001400,0x11080100,0x24000010,0x1071000,0x11080100,0x24000010,
+0x1071400,0x11080100,0x24000020,0x200000,0x11080100,0x24000020,0x400000,0x11080100,0x24000020,0x1600000,0x11080100,0x24000400,0x200000,0x11080100,0x24000420,0x200000,
+0x11080100,0x2c000010,0xb48000,0x11080100,0x2c000010,0x100ac00,0x11080100,0x44000001,0x1a40000,0x11080119,0x7c00100,0x220400,0x11080119,0x7c00100,0x250400,0x11080119,
+0x7c001c0,0x220400,0x11080119,0x7c001c0,0x250400,0x11080200,0x4000400,0x200002,0x11080200,0x24000000,0x200000,0x11080200,0x24000000,0x1500000,0x11080200,0x24000000,
+0x1600000,0x11080200,0x24000020,0x200000,0x110a1e12,0x7c00100,0x2130480,0x110a1e12,0x7c80100,0x2130480,0x110a3000,0x24100000,0x810001,0x110a3000,0x24100000,0x1410001,
+0x110a3d00,0x4000000,0xe00000,0x110a3d00,0x4000000,0xe00002,0x110a3d00,0x7c00300,0xe30000,0x110a3d00,0x7c00900,0xe30c00,0x110a3d00,0x24000000,0x810000,0x110a3d00,
+0x24000000,0xe00000,0x110a3d00,0x24000000,0x1410000,0x110a3d00,0x24000002,0xe00000,0x110a3d00,0x24000002,0x1200000,0x110a3d00,0x24000008,0x810000,0x110a3d00,0x24000008,
+0x1410000,0x110a3d00,0x24000010,0x870000,0x110a3d00,0x2c000010,0x848000,0x110a3d01,0x2802400,0x962460,0x110a3d11,0x7c00300,0xe30000,0x110a3d11,0x7c00900,0x1230400,
+0x110a3e00,0x7000400,0x1200c02,0x110a3e01,0x2802400,0x962460,0x110a3e14,0x7c00100,0xe30000,0x110a3e14,0x7c00100,0xe30001,0x110a3e14,0x7c00100,0x1230000,0x110a3e14,
+0x7c00900,0x1230000,0x110a3e14,0x7c00900,0x1230001,0x110a3f00,0x4000004,0x1200000,0x110a3f00,0x7c00d00,0x1230c00,0x110a3f16,0x7c00100,0xe30c00,0x110a3f16,0x7c00100,
+0xe30c01,0x110a3f16,0x7c00100,0x1230c00,0x110a3f16,0x7c00900,0x1230c00,0x110a3f16,0x7c00900,0x1230c01,0x110a4005,0x7c00100,0xe30400,0x110a4112,0x7c00100,0xe30402,
+0x110a4112,0x7c80100,0xe30402,0x110a4200,0x4000000,0xe00000,0x110a4200,0x4000000,0xe0000f,0x110a4400,0x4000000,0xe00000,0x110a4400,0x4000000,0xe00002,0x110a4400,
+0x4000000,0xe00003,0x110a4412,0x4000000,0xe00002,0x110a4412,0x4000000,0xe00003,0x110a4416,0x4000000,0xe00c03,0x110a4500,0x4000000,0xe00002,0x110a4500,0x4000000,
+0xe0000d,0x110a4516,0x4000000,0xe00c0d,0x110a4711,0x7c40300,0xe30000,0x110a4f11,0x7c00300,0xe30001,0x110a4f11,0x7c40300,0xe30000,0x110a5300,0x4000000,0x810010,
+0x110a5300,0x4000000,0xe00002,0x110a5300,0x4000000,0xe00010,0x110a5300,0x4000000,0x1410010,0x110a5300,0x4000002,0xe70010,0x110a5300,0x4000008,0x810010,0x110a5300,
+0x4000008,0x1410010,0x110a5300,0x6800000,0xe01c02,0x110a5300,0x6800000,0xe01c10,0x110a5400,0x4000000,0x81000c,0x110a5400,0x4000000,0xe0000c,0x110a5400,0x4000000,
+0x141000c,0x110a5400,0x4000000,0x150000c,0x110a5400,0x4000000,0x160000c,0x110a5400,0x4000002,0xe7000c,0x110a5400,0x4000010,0x87140c,0x110a5400,0x4000010,0xe7000c,
+0x110a5400,0x4000010,0x120140c,0x110a5400,0x4000010,0x127100c,0x110a5400,0x4000020,0xe0000c,0x110a5400,0x4000026,0xe7000c,0x110a5400,0xc000010,0x80ac0c,0x110a5400,
+0xc000010,0xb4800c,0x20000067,0x1000,0,0x20000b13,0x2802400,0x962460,0x20000b13,0x2802500,0x962460,0x20001b27,0x2802100,0x962460,0x20001b27,0x2802100,
+0x962461,0x20001b27,0x2802400,0x962460,0x20001b27,0x2806400,0x962460,0x20001b27,0x2902100,0x962462,0x20001b27,0x4000000,0x200000,0x20001b27,0x4000000,0x400000,
+0x20001b27,0x4000000,0x500000,0x20001b27,0x4000000,0x810000,0x20001b27,0x4000000,0xb00000,0x20001b27,0x4000000,0xc0000b,0x20001b27,0x4000000,0x1410000,0x20001b27,
+0x4000010,0xb00000,0x20001b27,0x4000010,0xc00000,0x20001b27,0x6800000,0x1329800,0x20001b27,0x6800100,0x462540,0x20001b27,0x6800400,0x962540,0x20001b27,0x7c00100,
+0x230400,0x20001b27,0x7c00100,0x230401,0x20002619,0x7c00100,0x220401,0x20002a00,0x4000000,0x1600000,0x20004b67,0,0x1900000,0x20004c67,0,0x1900000,
+0x20004d67,0,0x1900000,0x20006d67,0x1000,0,0x20006e67,0x1000,0,0x20026d67,0,0,0x20026e67,0,0,0x200a4a12,
+0x7c00100,0x1f304c1,0x200a4a12,0x7c00100,0x20304e1,0x21005600,0x4000000,0x700000,0x21022a00,0x4000000,0x1600000,0x30000419,0x7c00100,0x220400,0x30000419,0x7c00100,
+0x220401,0x30000419,0x7c00100,0x250400,0x30000419,0x7c00100,0x250401,0x30000519,0x7c00100,0x220400,0x30000600,0x4000400,0x200000,0x30000600,0x7c00500,0x230400,
+0x3000080e,0x7c00100,0x220400,0x30000908,0x2000,0x962460,0x30000908,0x7c00100,0x220400,0x30000908,0x7c00100,0x220401,0x30000908,0x7c00100,0x250400,0x30000908,
+0x7c00100,0x250401,0x30000a03,0x4000006,0x400000,0x30000c01,0x2802100,0x962460,0x30000c02,0x4000000,0x200000,0x30000c02,0x7c00100,0x230400,0x30000d22,0,
+0x218820,0x30000d22,0x2802100,0x962460,0x30000d22,0x2802400,0x962460,0x30000d22,0x2802500,0x962460,0x30000d22,0x4000000,0x200000,0x30000d22,0x4000010,0x200000,
+0x30000d22,0x7c00100,0x230400,0x30000d22,0xc000010,0x248000,0x30000e25,0x2802500,0x962460,0x30000e25,0x7c00100,0x230400,0x30001821,0x2802100,0x962460,0x30001821,
+0x2806400,0x962460,0x30001821,0x4000000,0x200000,0x30001821,0x6800100,0x962540,0x30001821,0x6800100,0x962541,0x30001821,0x7c00100,0x230400,0x30001b27,0x2802100,
+0x962460,0x30001b27,0x2802400,0x962460,0x30001b27,0x4000000,0x200000,0x30001b27,0x4000000,0x400000,0x30001b27,0x7c00100,0x230400,0x30001c1c,0x2802100,0x1862460,
+0x30001c1c,0x2802400,0x1862460,0x30001c1c,0x2806400,0x1862460,0x30001c1c,0x4000000,0x200000,0x30001c1c,0x6800000,0x1329800,0x30001c1c,0x6800100,0x1862540,0x30001c1c,
+0x7c00100,0x1830000,0x30001c1c,0x7c00100,0x1830001,0x30001c1c,0xc000010,0x448000,0x30001f0b,0x4000000,0x200000,0x30001f0b,0x4000010,0x200000,0x30001f0b,0x4000010,
+0x400000,0x30001f0b,0x6800000,0x200000,0x30001f0b,0x7c00100,0x230400,0x30001f0b,0xc000010,0x248000,0x30002006,0x7c00100,0x230400,0x30002128,0x4000010,0x200000,
+0x30002128,0x7c00100,0x230400,0x30002128,0xc000010,0x248000,0x3000221d,0x4000000,0x810000,0x3000221d,0x4000000,0x1410000,0x3000221d,0x4000001,0x440000,0x3000221d,
+0x7c00100,0x230400,0x30002300,0x4000010,0x400000,0x30002320,0x7c00100,0x230400,0x30002417,0x80000,0x1818820,0x30002417,0x2802100,0x1862460,0x30002417,0x2802400,
+0x1862460,0x30002417,0x2806400,0x1862460,0x30002417,0x4000000,0x200000,0x30002417,0x4000000,0x400000,0x30002417,0x4000000,0x1600000,0x30002417,0x4000010,0x400000,
+0x30002417,0x4000010,0x1200000,0x30002417,0x6800000,0x1329800,0x30002417,0x6800100,0x1862540,0x30002417,0x7c00100,0x1830000,0x30002417,0x7d00100,0x1830000,0x30002500,
+0x4000010,0x400000,0x30002500,0x4000010,0xb70000,0x30002500,0xc000010,0xb48000,0x3000251b,0x2802100,0x962460,0x3000251b,0x4000000,0x200000,0x3000251b,0x4000001,
+0xc40000,0x3000251b,0x4000006,0x500000,0x3000251b,0x4000010,0x400000,0x3000251b,0x4000010,0xb70000,0x3000251b,0x6800000,0x1329800,0x3000251b,0x7c00100,0x230400,
+0x3000251b,0x7c00900,0x230400,0x3000251b,0xc000010,0xb48000,0x3000251b,0x12882000,0x962460,0x30002800,0x4000001,0xc4000b,0x30002800,0x24000000,0x200000,0x30002800,
+0x2c000010,0x1248002,0x30002a00,0x4000000,0x1600000,0x30002b01,0x2000,0x962460,0x30002c00,0x4000000,0x200000,0x30002c00,0x7c00100,0x220405,0x30002d19,0x7c00100,
+0x250400,0x30002e00,0x24000000,0x200000,0x30003000,0x24000000,0x200000,0x30003100,0x24000000,0x200000,0x30003600,0x24000000,0x200000,0x30003700,0x24000000,0x200000,
+0x3000392e,0x24000000,0x200000,0x30005013,0x7c00100,0x230401,0x30005600,0,0x918820,0x30020600,0x4000400,0x500000,0x30020701,0x2802400,0x962460,0x30020701,
+0x2802400,0xc62460,0x300a3a11,0x4020000,0xe00000,0x300a3a11,0x4020000,0xe00002,0x300a3b11,0x4020000,0xe00002,0x300a3c00,0x4008000,0xe00000,0x300a3c00,0x4010000,
+0xe00000,0x300a3d00,0x4000000,0xe00000,0x300a3d11,0x7c00300,0xe30002,0x300a4305,0x7c00100,0xe30400,0x300a4611,0x7c40300,0xe30000,0x300a4829,0x7c00100,0xe30400,
+0x300a4829,0x7c00900,0x1230400,0x300a4929,0x4000000,0xe00000,0x3100080e,0x7c00120,0x220402,0x3100080e,0x7c00120,0x250402,0x31005167,0x1000,0,0x3100581e,
+0x4000000,0x200000,0x3100581e,0x7c00100,0x230400,0x3100590d,0x7c00100,0x230400,0x31005a09,0x7c00100,0x220400,0x31005a09,0x7c00100,0x250400,0x31005b00,0x4000000,
+0x200000,0x31005c00,0x80000,0x918820,0x31005c00,0x2802000,0x962460,0x31005c00,0x2802400,0x962460,0x31005c00,0x4000000,0x200000,0x31005c00,0x4000000,0x200001,
+0x31005c00,0x6800000,0x962540,0x31005c00,0x6800400,0x962540,0x31005c01,0x2802400,0x962460,0x31005d00,0x4000020,0x200005,0x31005d00,0x6800020,0x1329805,0x31005d00,
+0x7c00120,0x220405,0x31005d00,0x7c00120,0x250405,0x31006000,0x180000,0x918820,0x310a5e11,0x7c40300,0xe30000,0x310a5f11,0x7c00300,0xe30001,0x32000419,0x7c00100,
+0x250400,0x3200080e,0x4000020,0x200000,0x3200080e,0x7c00100,0x220400,0x3200080e,0x7c00100,0x250400,0x32000908,0x7c00100,0x220400,0x32000908,0x7c00100,0x250400,
+0x32000c02,0x7c00100,0x230400,0x32000e25,0x7c00100,0x230400,0x32001d0c,0x7c00100,0x230400,0x32002800,0x80000,0x1e18820,0x32002800,0x80020,0x218820,0x32002800,
+0x4000001,0x440002,0x32002800,0x24000000,0x200000,0x32002800,0x24000000,0x200002,0x32002800,0x24000020,0x200000,0x32002800,0x2c000010,0x1248002,0x32002919,0x7c00100,
+0x23040f,0x32002a00,0x4000000,0x1600000,0x32002b01,0x2000,0x962460,0x32002b01,0x2802000,0x962460,0x32002b01,0x2802020,0x962460,0x32002c00,0x4000000,0x200000,
+0x32002c00,0x4000020,0x200000,0x32002c00,0x4000020,0x200005,0x32002c00,0x7c00120,0x220405,0x32002c00,0x7c00120,0x250405,0x32002e00,0x24000020,0x200000,0x32002f00,
+0x24000020,0x200000,0x32003000,0x24000000,0x200000,0x32003000,0x24000020,0x200000,0x32003500,0x24000000,0x200000,0x32003600,0x24000020,0x200000,0x32003700,0x24000000,
+0x100000,0x32003700,0x24000000,0x200000,0x32003800,0x24000000,0x810000,0x32003800,0x24000000,0x1410000,0x32005102,0x4000000,0x1500008,0x32005502,0x7c00100,0x230400,
+0x32006108,0x7c00100,0x220400,0x32006108,0x7c00100,0x250400,0x3200622a,0x2802100,0x962460,0x3200622a,0x2806000,0x962460,0x3200622a,0x7c00100,0x230400,0x32006300,
+0x4000000,0x400000,0x3200632b,0x2802100,0x962460,0x3200632b,0x2806000,0x962460,0x3200632b,0x7c00100,0x230400,0x3200642c,0x2802100,0x962460,0x3200642c,0x7c00100,
+0x230400,0x3200652d,0x2802100,0x962460,0x3200652d,0x7c00100,0x230400,0x32006600,0x24000020,0x200000,0x32006700,0x24000020,0x200000,0x32006800,0x24000020,0x200000,
+0x32006900,0x24000020,0x200000,0x32006900,0x24000020,0x810000,0x32006900,0x24000020,0x1410000,0x32006a00,0x24000020,0x200000,0x32006a00,0x24000020,0x200001,0x32006a00,
+0x24000020,0x200002,0x32020701,0x2802000,0x962460,0x32020701,0x2882000,0xc62460,0x32023300,0x4000000,0x100000,0x32026c01,0x12882000,0x962460,0x32065700,0x4000000,
+0x810011,0x32065700,0x4000000,0x1410011,0x32086600,0x24000020,0x810000,0x32086600,0x24000020,0x1410000,0x32086900,0x24000020,0x810000,0x32086900,0x24000020,0x1410000,
+0x320a3d00,0x4000000,0xe00000,0x320a3d00,0x7c00100,0x1230400,0x320a3d11,0x7c00100,0x1230400,0x320a3e14,0x7c00100,0xe30010,0x320a3e14,0x7c00100,0x1230000,0x320a3f00,
+0x4000002,0x1200c00,0x320a3f16,0x7c00100,0xe30c10,0x320a4400,0x4000000,0xe00003,0x320a4929,0x4000000,0xe00000,0x320a4f11,0x7c00300,0xe30001,0x320a5300,0x24000000,
+0xe00000,0x320a6b16,0x7c00100,0x1230c00,0x40000419,0x7c00100,0x220400,0x40000519,0x7c00100,0x220400,0x40000600,0x4000400,0x200000,0x4000080e,0x7c00100,0x220400,
+0x4000080e,0x7c00100,0x250400,0x4000080e,0x7c00100,0x250402,0x40000c00,0,0x218820,0x40000c02,0x2802100,0x962460,0x40000c02,0x2802400,0x962460,0x40000c02,
+0x2802500,0x962460,0x40000c02,0x4000000,0x200000,0x40000c02,0x4000000,0x1071400,0x40000c02,0x7c00100,0x230400,0x40000d22,0x7c00100,0x230400,0x40000f0a,0x7c00100,
+0x230400,0x40001004,0x7c00100,0x230400,0x40001110,0x2802100,0x962460,0x40001110,0x6800100,0x962540,0x4000120f,0x2802100,0x962460,0x4000120f,0x4000000,0x1600000,
+0x4000120f,0x7c00100,0x230400,0x4000131f,0x7c00100,0x230400,0x40001423,0x4000000,0x200000,0x40001423,0x4000000,0x1600000,0x40001615,0x2802400,0x962460,0x40001615,
+0x7c00100,0x230400,0x40002417,0x2802400,0x1862460,0x40002417,0x4000000,0x200000,0x40002800,0x6800000,0x201c00,0x40002800,0x24000002,0x200000,0x40002c00,0x4000000,
+0x200002,0x40003000,0x24000000,0x200000,0x40003000,0x24000020,0x200000,0x40003700,0x24000000,0x200000,0x40005100,0x4000000,0x200000,0x40005a09,0x7c00100,0x220400,
+0x40005a09,0x7c00100,0x250400,0x40005d00,0x7c00120,0x220405,0x40006f30,0x2802100,0x962460,0x40006f30,0x2802400,0x962460,0x40006f30,0x4000000,0x200000,0x40006f30,
+0x6800000,0x1329800,0x40006f30,0x6800100,0x962540,0x40006f30,0x7c00100,0x230400,0x40006f30,0xc000010,0xb48000,0x40007034,0x7c00100,0x1830000,0x40007117,0x4000000,
+0x200000,0x40007208,0x7c00100,0x220400,0x4000720e,0x7c00100,0x220400,0x4000720e,0x7c00500,0x22040e,0x4000720e,0x7c00500,0x22040f,0x40007219,0x7c00100,0x220400,
+0x40007219,0x7c00500,0x220400,0x40007219,0x7c00500,0x22040e,0x40007219,0x7c00500,0x22040f,0x40007300,0x24000000,0x200000,0x40007400,0x4000000,0x200000,0x40007531,
+0x7c00100,0x230400,0x40007631,0x7c00100,0x230400,0x40007700,0x4000000,0x200000,0x40007700,0x4000000,0x400000,0x40007835,0x4000010,0x400000,0x40007835,0x7c00100,
+0x230400,0x40007933,0x7c00100,0x230400,0x40007a32,0x6800000,0x1329800,0x40007a32,0x7c00100,0x230400,0x40007b2f,0x7c00100,0x230400,0x40007c00,0x4000000,0x200000,
+0x40020701,0x2802400,0x962460,0x40020701,0x2802400,0xc62460,0x40023300,0x4000000,0x200000,0x40023700,0x24000000,0x100000,0x40027d01,0x12882000,0x962460,0x400a4400,
+0x4000000,0xe0000d,0x400a4412,0x4000000,0xe00002,0x400a4412,0x4000000,0xe00003,0x400a4500,0x4000000,0xe0000d,0x400a5300,0x4000000,0x810010,0x400a5300,0x4000000,
+0x1410010,0x41000419,0x7c00100,0x220400,0x41000419,0x7c00100,0x250400,0x4100080e,0x7c00100,0x220400,0x4100080e,0x7c00100,0x250400,0x41000908,0x7c00100,0x220400,
+0x41000908,0x7c00100,0x250400,0x41000b13,0x2802000,0x962460,0x41000b13,0x2802100,0x962460,0x41000b13,0x4000000,0xb00000,0x41000c02,0x2802100,0x962460,0x41000c02,
+0x4000000,0xb00000,0x41000c02,0x4000000,0x1500000,0x41000f0a,0x7c00100,0x230400,0x41001004,0x7c00100,0x230400,0x41001423,0x6800000,0x1329800,0x41001423,0x7c00100,
+0x230400,0x41001b27,0x4000000,0x500000,0x41001d0c,0x7c00100,0x230400,0x41001d0c,0x7c00100,0x23040f,0x41001f0b,0x2802100,0x962460,0x41001f0b,0x4000000,0x200000,
+0x41001f0b,0x7c00100,0x230400,0x41002800,0x24000000,0x200000,0x41002800,0x24000000,0x400000,0x41002919,0x7c00100,0x22040e,0x41002a00,0x4000000,0x1600000,0x41002b01,
+0x2802020,0x962460,0x41002c00,0x4000000,0x200000,0x41002c00,0x7c00120,0x220405,0x41003000,0x24000000,0x200000,0x41003700,0x24000000,0x200000,0x41005d00,0x7c00120,
+0x220405,0x41006600,0x24000020,0x200000,0x41006600,0x24000020,0x810000,0x41006600,0x24000020,0x1410000,0x41007208,0x7c00100,0x22040f,0x41007219,0x7c00100,0x220400,
+0x41007300,0x24000000,0x200000,0x41007e0e,0x2802000,0x962460,0x41007e0e,0x4000000,0x200000,0x41007f0e,0x4000000,0x200000,0x41007f0e,0x7c00100,0x230400,0x41008002,
+0x7c00100,0x230400,0x41008137,0x2802100,0x962460,0x41008137,0x4000000,0x200000,0x41008137,0x6800100,0x962540,0x41008137,0x7c00100,0x230400,0x41008301,0x2802000,
+0x962460,0x41008407,0x4000000,0x200000,0x41008407,0x4000000,0x400000,0x41008407,0x4000000,0xb00000,0x41008407,0x7c00100,0x220400,0x41008407,0x7c00100,0x250400,
+0x4100850b,0x7c00100,0x230400,0x4100860b,0x4000000,0x200000,0x4100860b,0x7c00100,0x230400,0x4100870c,0x7c00100,0x220400,0x41008838,0x7c00100,0x220400,0x41008838,
+0x7c00100,0x250400,0x41008939,0x2802000,0x962460,0x41008939,0x2802100,0x962460,0x41008939,0x2806000,0x962460,0x41008939,0x4000000,0x200000,0x41008939,0x4000000,
+0x400000,0x41008939,0x7c00100,0x230400,0x41008a00,0x4000000,0x200000,0x41008b3b,0x4000000,0x1800000,0x41008b3b,0x6800000,0x1329800,0x41008b3b,0x6800100,0x1862540,
+0x41008b3b,0x7c00100,0x1830000,0x41008c3d,0x4000010,0x400000,0x41008c3d,0x7c00100,0x230400,0x41008d0e,0x7c00100,0x22040f,0x41008d19,0x7c00100,0x220400,0x41008d19,
+0x7c00100,0x22040f,0x41008e00,0x24000000,0x200000,0x41008e00,0x24000000,0x400000,0x41008e00,0x24000000,0x1710000,0x41008e00,0x24000006,0x400000,0x41008f3a,0x2802000,
+0x962460,0x41008f3a,0x2802100,0x962460,0x41008f3a,0x2806000,0x962460,0x41008f3a,0x4000000,0x200000,0x41008f3a,0x6800100,0x962540,0x41008f3a,0x7c00100,0x230400,
+0x4100903c,0x7c00100,0x230400,0x4100903c,0x7c00100,0x23040f,0x41020701,0x2802000,0x962460,0x41020701,0x2802000,0xc62460,0x410a4412,0x4000000,0xe00003,0x410a4711,
+0x7c40300,0xe30000,0x410a4f11,0x7c00300,0xe30001,0x410a8200,0x4000000,0xe00000,0x410a9100,0x4000000,0x800010,0x410a9100,0x4000000,0x810010,0x410a9100,0x4000000,
+0x870010,0x410a9100,0x4000000,0xb00010,0x410a9100,0x4000000,0xf00010,0x410a9100,0x4000000,0x1001410,0x410a9100,0x4000000,0x1071010,0x410a9100,0x4000000,0x1071410,
+0x410a9100,0x4000000,0x1410010,0x50000419,0x7c00100,0x220400,0x50000419,0x7c00100,0x250400,0x5000080e,0x7c00100,0x220400,0x50000908,0x7c00100,0x220400,0x50000908,
+0x7c00100,0x250400,0x50000b13,0x2802500,0x962460,0x50000f0a,0x7c00100,0x230400,0x50001600,0x4000000,0x200000,0x50001615,0x2802100,0x962460,0x50002b01,0x2802020,
+0x962460,0x50002c00,0x4000000,0x200000,0x50002c19,0x7c00100,0x220400,0x50002d19,0x7c00100,0x220400,0x50003000,0x24000000,0x200000,0x50003000,0x24000020,0x200000,
+0x50003700,0x24000000,0x200000,0x50005d00,0x7c00120,0x220405,0x50005d00,0x7c00120,0x250405,0x50006108,0x7c00100,0x220400,0x50006108,0x7c00100,0x250400,0x50006600,
+0x24000020,0x200000,0x50007300,0x24000000,0x200000,0x50008301,0x2802400,0x962460,0x50008a00,0x7c00500,0x230400,0x50009257,0x2802400,0x962460,0x50009257,0x4000000,
+0x200000,0x50009257,0x4000010,0x1071400,0x50009257,0x6800000,0x1329800,0x50009257,0x7c00100,0x230400,0x50009257,0x7c00500,0x230400,0x50009257,0x7c00900,0x230400,
+0x50009257,0xc000010,0xb48000,0x5000933e,0x2802100,0x962460,0x5000933e,0x2802400,0x962460,0x5000933e,0x4000000,0x200000,0x5000933e,0x4000000,0x400000,0x5000933e,
+0x4000010,0x400000,0x5000933e,0x6800000,0x1329800,0x5000933e,0x6800100,0x962540,0x5000933e,0x6800100,0x962541,0x5000933e,0x6804400,0x962540,0x5000933e,0x7c00100,
+0x230400,0x5000933e,0x7c00100,0x230401,0x5000933e,0xc000010,0x448000,0x50009419,0x7c00100,0x220400,0x50009419,0x7c00100,0x250400,0x50009500,0x4000400,0x200000,
+0x5000965a,0x4000000,0x500000,0x5000965a,0x7c00100,0x230400,0x5000965a,0xc000010,0xb48000,0x5000975b,0x4000000,0x200000,0x5000975b,0x4000010,0x400000,0x5000975b,
+0x7c00100,0x230400,0x50009865,0x7c00100,0x230400,0x50009965,0x4000010,0x400000,0x50009965,0x7c00100,0x230400,0x50009a00,0x4000000,0x200000,0x5100080e,0x7c00100,
+0x220400,0x5100080e,0x7c00100,0x250400,0x51000908,0x2802400,0x962460,0x51000c02,0x2802100,0x962460,0x51000c02,0x4000000,0x1500000,0x51000c02,0x4000020,0x200000,
+0x51000c02,0x7c00100,0x230400,0x51000f0a,0x7c00100,0x230400,0x51000f0a,0x7c00500,0x230400,0x51001110,0x2802100,0x962460,0x5100131f,0x2802100,0x962460,0x51001423,
+0x7c00100,0x230400,0x51001524,0x2802100,0x962460,0x51001524,0x4000000,0x200000,0x51001524,0x7c00100,0x230400,0x5100171a,0x2802100,0x962460,0x5100171a,0x4000000,
+0x200000,0x5100171a,0x4000000,0x1500000,0x5100171a,0x7c00100,0x230400,0x51001b27,0x4000000,0x200000,0x51001b27,0x4000000,0x400000,0x51001b27,0x4000000,0x500000,
+0x51001b27,0x7c00100,0x230400,0x51001c1c,0x2802100,0x1862460,0x51001c1c,0x2802400,0x1862460,0x51001c1c,0x2806400,0x1862460,0x51001c1c,0x4000000,0x1800000,0x51001c1c,
+0x6800000,0x1329800,0x51001c1c,0x6800000,0x1862540,0x51001c1c,0x6800100,0x1862540,0x51001c1c,0x6800400,0x1862540,0x51001c1c,0x7c00100,0x1830000,0x5100251b,0x7c00100,
+0x230400,0x51002619,0x7c00100,0x220400,0x51002619,0x7c00100,0x250400,0x51002800,0x80020,0x218820,0x51002b01,0x2802000,0x962460,0x51002c00,0x4000000,0x200000,
+0x51002d19,0x7c00100,0x230400,0x51003700,0x24000000,0x200000,0x51005201,0x2802400,0x962460,0x51005c00,0x4000000,0x200000,0x51006108,0x7c00100,0x220400,0x51006108,
+0x7c00100,0x250400,0x51006600,0x24000020,0x200000,0x51006600,0x24000020,0x810000,0x51006600,0x24000020,0x1410000,0x51007300,0x24000000,0x200000,0x51007300,0x24000020,
+0x200000,0x51008002,0x7c00100,0x230400,0x51008301,0x2802000,0x962460,0x51008301,0x2802400,0x962460,0x51008a00,0x7c00500,0x230400,0x51008e00,0x24000000,0x200000,
+0x51008e00,0x24000000,0x400000,0x51008e00,0x24000000,0x810000,0x51008e00,0x24000000,0x1400000,0x51008e00,0x24000000,0x1410000,0x51008e00,0x24000000,0x1710000,0x51008e00,
+0x24000002,0x200000,0x51008e00,0x24000500,0x230400,0x51008e00,0x2c000010,0xb48000,0x51009419,0x7c00100,0x220400,0x51009419,0x7c00100,0x22040e,0x51009419,0x7c00100,
+0x22040f,0x51009419,0x7c00100,0x250400,0x51009500,0x4000000,0x200000,0x51009500,0x7c00500,0x230400,0x51009519,0x7c00100,0x220400,0x51009519,0x7c00100,0x22040f,
+0x51009519,0x7c00100,0x230400,0x51009519,0x7c00100,0x250400,0x51009b71,0x2802100,0x962460,0x51009b71,0x6800000,0x1329800,0x51009b71,0x6800100,0x962540,0x51009b71,
+0x6804400,0x962540,0x51009b71,0x7c00100,0x230400,0x51009c52,0x2802100,0x962460,0x51009c52,0x2802400,0x962460,0x51009c52,0x2802c00,0x962460,0x51009c52,0x4000010,
+0x400000,0x51009c52,0x6800000,0x1329800,0x51009c52,0x6800100,0x962540,0x51009c52,0x7c00100,0x230400,0x51009c52,0xc000010,0x448000,0x51009d6d,0x6800000,0x1329800,
+0x51009d6d,0x7c00100,0x230400,0x51009d6d,0x7c00500,0x230400,0x51009d6d,0x7c00d00,0x230400,0x51009d6d,0xc000010,0x448000,0x51009e08,0x2802100,0x962460,0x51009f63,
+0x4000010,0x400000,0x51009f63,0x6800000,0x1329800,0x51009f63,0x7c00100,0x230400,0x51009f63,0x7c00900,0x230400,0x51009f63,0xc000010,0x448000,0x51009f63,0xc000010,
+0xb48000,0x5100a008,0x2000,0x962460,0x5100a008,0x2802400,0x962460,0x5100a008,0x4000000,0x200000,0x5100a008,0x7c00100,0x220400,0x5100a008,0x7c00100,0x230400,
+0x5100a008,0x7c00100,0x250400,0x5100a008,0x7c00500,0x230400,0x5100a16f,0x2806400,0x962460,0x5100a16f,0x6800000,0x1329800,0x5100a16f,0x6800100,0x962540,0x5100a16f,
+0x7c00100,0x230400,0x5100a16f,0xc000010,0x448000,0x5100a24f,0x2802100,0x962460,0x5100a24f,0x2802400,0x962460,0x5100a24f,0x4000400,0x400000,0x5100a24f,0x6800000,
+0x1329800,0x5100a24f,0x7c00100,0x230400,0x5100a24f,0xc000010,0x448000,0x5100a36e,0x2802100,0x962460,0x5100a36e,0x4000000,0x200000,0x5100a36e,0x6800100,0x962540,
+0x5100a36e,0x6804400,0x962540,0x5100a36e,0x7c00100,0x230400,0x5100a442,0x2802100,0x962460,0x5100a442,0x4000000,0x200000,0x5100a442,0x6800000,0x1329800,0x5100a442,
+0x6800100,0x962540,0x5100a442,0x7c00100,0x230400,0x5100a442,0xc000010,0x448000,0x5100a500,0x4000000,0x200000,0x5100a600,0x4000000,0x200000,0x5100a601,0x2802000,
+0x962460,0x5100a76b,0x7c00100,0x230400,0x5100a868,0x7c00100,0x230400,0x5100a96c,0x4000000,0x200000,0x5100a96c,0x7c00100,0x230400,0x5100aa00,0x4000000,0x200000,
+0x5100ab00,0x4000000,0x200000,0x51086600,0x24000020,0x810000,0x51086600,0x24000020,0x1410000,0x510a4005,0x7c00100,0xe30400,0x510a4711,0x7c40300,0xe30000,0x510a8200,
+0x4000000,0xe00000,0x52000f0a,0x2802100,0x962460,0x52000f0a,0x6800100,0x962540,0x52000f0a,0x7c00100,0x230400,0x52001004,0x4000000,0x1600000,0x52001b00,0x4000000,
+0x200000,0x52001c1c,0x2802100,0x1862460,0x52001c1c,0x6800100,0x1862540,0x52001c1c,0x6800400,0x1862540,0x52002128,0x4000002,0x400000,0x52002128,0x7c00100,0x230400,
+0x52002a00,0x4000000,0x1500000,0x52002a00,0x4000000,0x1600000,0x52002d00,0x4000000,0x200006,0x52003000,0x24000000,0x200000,0x52003700,0x24000000,0x200000,0x52006108,
+0x7c00100,0x220400,0x52006108,0x7c00100,0x250400,0x52008301,0x2802400,0x962460,0x52008407,0x2802400,0x962460,0x52008407,0x7c00100,0x220400,0x52008407,0x7c00100,
+0x250400,0x52008b3b,0x6800000,0x1329800,0x52008b3b,0x7c00100,0x1830000,0x52008e00,0x24000000,0x400000,0x52009419,0x7c00100,0x250400,0x5200975b,0x4000000,0x200000,
+0x5200ac7e,0x2802000,0x962460,0x5200ac7e,0x2802100,0x962460,0x5200ac7e,0x2802400,0x962460,0x5200ac7e,0x4000010,0x200000,0x5200ac7e,0x7c00100,0x230400,0x5200ad28,
+0x7c00100,0x230400,0x5200ae6a,0x2802100,0x1862460,0x5200ae6a,0x2802400,0x962460,0x5200ae6a,0x2802400,0x1862460,0x5200ae6a,0x2806000,0x1862460,0x5200ae6a,0x4000000,
+0x1800000,0x5200ae6a,0x4000010,0x1800000,0x5200ae6a,0x6800000,0x1329800,0x5200ae6a,0x6800100,0x1862540,0x5200ae6a,0x7c00100,0x1830000,0x5200ae6a,0x7c00900,0x1830000,
+0x5200af00,0x4000400,0x200000,0x5200af00,0x6800100,0x962540,0x5200af00,0x6800400,0x962540,0x5200af00,0x7c00100,0x230400,0x5200af01,0x2802400,0x962460,0x5200b083,
+0x4000010,0x400000,0x5200b083,0x7c00100,0x230400,0x5200b083,0xc000010,0x448000,0x5200b182,0x2802400,0x962460,0x5200b182,0x4000000,0x200000,0x5200b182,0x4000010,
+0x400000,0x5200b182,0x7c00100,0x230400,0x5200b182,0xc000010,0x448000,0x5200b200,0x4000000,0x200000,0x5200b200,0x4000000,0x1500000,0x5200b30a,0x2802400,0x962460,
+0x5200b30a,0x4000000,0x200000,0x5200b30a,0x7c00100,0x230400,0x5200b54e,0x2802100,0x962460,0x5200b54e,0x2802500,0x962460,0x5200b54e,0x4000000,0x200000,0x5200b54e,
+0x4000010,0x400000,0x5200b54e,0x6800000,0x1329800,0x5200b54e,0x6800100,0x962540,0x5200b54e,0x6804400,0x962540,0x5200b54e,0x7c00100,0x230400,0x5200b54e,0x7c00900,
+0x230400,0x5200b54e,0xc000010,0x448000,0x5200b61c,0x4000000,0x1800000,0x5200b61c,0x6800400,0x1862540,0x5200b61c,0x7c00100,0x1830000,0x5200b61c,0x7c00900,0x1830000,
+0x5200b77f,0x2802100,0x1862460,0x5200b77f,0x2802400,0x1862460,0x5200b77f,0x4000000,0x1800000,0x5200b77f,0x4000010,0x1800000,0x5200b77f,0x7c00100,0x1830000,0x5200b77f,
+0x7c00500,0x1830000,0x5200b77f,0x7c00900,0x1830000,0x5200b77f,0x7e00100,0x1830160,0x5200b873,0x2802100,0x962460,0x5200b873,0x2806400,0x962460,0x5200b873,0x6800000,
+0x1329800,0x5200b873,0x6800100,0x962540,0x5200b873,0x6800400,0x962540,0x5200b873,0x7c00100,0x230400,0x5200b873,0xc000010,0x448000,0x5200ba74,0x4000000,0x200000,
+0x5200ba74,0x4000010,0x400000,0x5200ba74,0x7c00100,0x230400,0x5200bb85,0x4000000,0x200000,0x5200bb85,0x7c00100,0x230400,0x5200bc75,0x4000000,0x400000,0x5200bc75,
+0x4000010,0x400000,0x5200bc75,0x7c00100,0x230400,0x5200bd7d,0x4000000,0x200000,0x5200bd7d,0x7c00100,0x230400,0x5200be7a,0x4000000,0x200000,0x5200be7a,0x7c00100,
+0x230400,0x5200bf58,0x7c00100,0x230400,0x5200c002,0x4000000,0x200000,0x5200c178,0,0x218820,0x5200c178,0x2802000,0x962460,0x5200c178,0x2802100,0x962460,
+0x5200c178,0x2802400,0x962460,0x5200c178,0x2806400,0x962460,0x5200c178,0x4000000,0x200000,0x5200c178,0x6800100,0x962540,0x5200c178,0x7c00100,0x230400,0x5200c178,
+0x7c00100,0x230401,0x5200c178,0xc000010,0x448000,0x5200c247,0x7c00100,0x230400,0x5200c247,0x7c00100,0x830400,0x5200c247,0x7c00100,0x1430400,0x5200c300,0x4000000,
+0x200003,0x52022d00,0x4000000,0x100006,0x52023700,0x24000000,0x100000,0x52023800,0x24000000,0x100000,0x52024400,0x4000000,0x100000,0x52027300,0x24000000,0x100000,
+0x5202c300,0x4000000,0x100000,0x5202c300,0x4000000,0x100002,0x5202c300,0x4000000,0x100003,0x5202c300,0x4000000,0x10000d,0x520a1e12,0x7c00100,0x2130480,0x520a1e12,
+0x7c00100,0x2230500,0x520a1e12,0x7c00100,0x2330520,0x520a4400,0x4000000,0xe00003,0x520a4711,0x7c40300,0xe30000,0x520a4f11,0x7c00300,0xe30001,0x520ab412,0x7c00100,
+0x2130480,0x520ab912,0x7c00100,0x2230500,0x520ab912,0x7c00100,0x2330520,0x520ac400,0x4000000,0xe00002,0x520ac400,0x4000000,0xe0000d,0x520ac414,0x4000000,0xe0000d,
+0x520ac511,0x7c40300,0xe30000};
+
+static const int32_t countPropsVectors=4371;
+static const int32_t propsVectorsColumns=3;
+static const int32_t indexes[UPROPS_INDEX_COUNT]={0x1e30,0x1e30,0x1e30,0x1e30,0x4598,3,0x56ab,0,0,0,0xac585,0x2473171,0,0,0,0};
+
diff --git a/icu/source/common/uchriter.cpp b/icu/source/common/uchriter.cpp
new file mode 100644
index 0000000..ae73695
--- /dev/null
+++ b/icu/source/common/uchriter.cpp
@@ -0,0 +1,363 @@
+/*
+******************************************************************************
+* Copyright (C) 1998-2004, International Business Machines Corporation and   *
+* others. All Rights Reserved.                                               *
+******************************************************************************
+*/
+
+#include "unicode/uchriter.h"
+#include "unicode/ustring.h"
+#include "uhash.h"
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UCharCharacterIterator)
+
+UCharCharacterIterator::UCharCharacterIterator()
+  : CharacterIterator(),
+  text(0)
+{
+    // never default construct!
+}
+
+UCharCharacterIterator::UCharCharacterIterator(const UChar* textPtr,
+                                               int32_t length)
+  : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0),
+  text(textPtr)
+{
+}
+
+UCharCharacterIterator::UCharCharacterIterator(const UChar* textPtr,
+                                               int32_t length,
+                                               int32_t position)
+  : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0, position),
+  text(textPtr)
+{
+}
+
+UCharCharacterIterator::UCharCharacterIterator(const UChar* textPtr,
+                                               int32_t length,
+                                               int32_t textBegin,
+                                               int32_t textEnd,
+                                               int32_t position)
+  : CharacterIterator(textPtr != 0 ? (length>=0 ? length : u_strlen(textPtr)) : 0, textBegin, textEnd, position),
+  text(textPtr)
+{
+}
+
+UCharCharacterIterator::UCharCharacterIterator(const UCharCharacterIterator& that)
+: CharacterIterator(that),
+  text(that.text)
+{
+}
+
+UCharCharacterIterator&
+UCharCharacterIterator::operator=(const UCharCharacterIterator& that) {
+    CharacterIterator::operator=(that);
+    text = that.text;
+    return *this;
+}
+
+UCharCharacterIterator::~UCharCharacterIterator() {
+}
+
+UBool
+UCharCharacterIterator::operator==(const ForwardCharacterIterator& that) const {
+    if (this == &that) {
+        return TRUE;
+    }
+    
+    if (getDynamicClassID() != that.getDynamicClassID()) {
+        return FALSE;
+    }
+
+    UCharCharacterIterator&    realThat = (UCharCharacterIterator&)that;
+
+    return text == realThat.text
+        && textLength == realThat.textLength
+        && pos == realThat.pos
+        && begin == realThat.begin
+        && end == realThat.end;
+}
+
+int32_t
+UCharCharacterIterator::hashCode() const {
+    return uhash_hashUCharsN(text, textLength) ^ pos ^ begin ^ end;
+}
+
+CharacterIterator*
+UCharCharacterIterator::clone() const {
+    return new UCharCharacterIterator(*this);
+}
+
+UChar
+UCharCharacterIterator::first() {
+    pos = begin;
+    if(pos < end) {
+        return text[pos];
+    } else {
+        return DONE;
+    }
+}
+
+UChar
+UCharCharacterIterator::firstPostInc() {
+    pos = begin;
+    if(pos < end) {
+        return text[pos++];
+    } else {
+        return DONE;
+    }
+}
+
+UChar
+UCharCharacterIterator::last() {
+    pos = end;
+    if(pos > begin) {
+        return text[--pos];
+    } else {
+        return DONE;
+    }
+}
+
+UChar
+UCharCharacterIterator::setIndex(int32_t position) {
+    if(position < begin) {
+        pos = begin;
+    } else if(position > end) {
+        pos = end;
+    } else {
+        pos = position;
+    }
+    if(pos < end) {
+        return text[pos];
+    } else {
+        return DONE;
+    }
+}
+
+UChar
+UCharCharacterIterator::current() const {
+    if (pos >= begin && pos < end) {
+        return text[pos];
+    } else {
+        return DONE;
+    }
+}
+
+UChar
+UCharCharacterIterator::next() {
+    if (pos + 1 < end) {
+        return text[++pos];
+    } else {
+        /* make current() return DONE */
+        pos = end;
+        return DONE;
+    }
+}
+
+UChar
+UCharCharacterIterator::nextPostInc() {
+    if (pos < end) {
+        return text[pos++];
+    } else {
+        return DONE;
+    }
+}
+
+UBool
+UCharCharacterIterator::hasNext() {
+    return (UBool)(pos < end ? TRUE : FALSE);
+}
+
+UChar
+UCharCharacterIterator::previous() {
+    if (pos > begin) {
+        return text[--pos];
+    } else {
+        return DONE;
+    }
+}
+
+UBool
+UCharCharacterIterator::hasPrevious() {
+    return (UBool)(pos > begin ? TRUE : FALSE);
+}
+
+UChar32
+UCharCharacterIterator::first32() {
+    pos = begin;
+    if(pos < end) {
+        int32_t i = pos;
+        UChar32 c;
+        UTF_NEXT_CHAR(text, i, end, c);
+        return c;
+    } else {
+        return DONE;
+    }
+}
+
+UChar32
+UCharCharacterIterator::first32PostInc() {
+    pos = begin;
+    if(pos < end) {
+        UChar32 c;
+        UTF_NEXT_CHAR(text, pos, end, c);
+        return c;
+    } else {
+        return DONE;
+    }
+}
+
+UChar32
+UCharCharacterIterator::last32() {
+    pos = end;
+    if(pos > begin) {
+        UChar32 c;
+        UTF_PREV_CHAR(text, begin, pos, c);
+        return c;
+    } else {
+        return DONE;
+    }
+}
+
+UChar32
+UCharCharacterIterator::setIndex32(int32_t position) {
+    if(position < begin) {
+        position = begin;
+    } else if(position > end) {
+        position = end;
+    }
+    if(position < end) {
+        UTF_SET_CHAR_START(text, begin, position);
+        int32_t i = this->pos = position;
+        UChar32 c;
+        UTF_NEXT_CHAR(text, i, end, c);
+        return c;
+    } else {
+        this->pos = position;
+        return DONE;
+    }
+}
+
+UChar32
+UCharCharacterIterator::current32() const {
+    if (pos >= begin && pos < end) {
+        UChar32 c;
+        UTF_GET_CHAR(text, begin, pos, end, c);
+        return c;
+    } else {
+        return DONE;
+    }
+}
+
+UChar32
+UCharCharacterIterator::next32() {
+    if (pos < end) {
+        UTF_FWD_1(text, pos, end);
+        if(pos < end) {
+            int32_t i = pos;
+            UChar32 c;
+            UTF_NEXT_CHAR(text, i, end, c);
+            return c;
+        }
+    }
+    /* make current() return DONE */
+    pos = end;
+    return DONE;
+}
+
+UChar32
+UCharCharacterIterator::next32PostInc() {
+    if (pos < end) {
+        UChar32 c;
+        UTF_NEXT_CHAR(text, pos, end, c);
+        return c;
+    } else {
+        return DONE;
+    }
+}
+
+UChar32
+UCharCharacterIterator::previous32() {
+    if (pos > begin) {
+        UChar32 c;
+        UTF_PREV_CHAR(text, begin, pos, c);
+        return c;
+    } else {
+        return DONE;
+    }
+}
+
+int32_t
+UCharCharacterIterator::move(int32_t delta, CharacterIterator::EOrigin origin) {
+    switch(origin) {
+    case kStart:
+        pos = begin + delta;
+        break;
+    case kCurrent:
+        pos += delta;
+        break;
+    case kEnd:
+        pos = end + delta;
+        break;
+    default:
+        break;
+    }
+
+    if(pos < begin) {
+        pos = begin;
+    } else if(pos > end) {
+        pos = end;
+    }
+
+    return pos;
+}
+
+int32_t
+UCharCharacterIterator::move32(int32_t delta, CharacterIterator::EOrigin origin) {
+    // this implementation relies on the "safe" version of the UTF macros
+    // (or the trustworthiness of the caller)
+    switch(origin) {
+    case kStart:
+        pos = begin;
+        if(delta > 0) {
+            UTF_FWD_N(text, pos, end, delta);
+        }
+        break;
+    case kCurrent:
+        if(delta > 0) {
+            UTF_FWD_N(text, pos, end, delta);
+        } else {
+            UTF_BACK_N(text, begin, pos, -delta);
+        }
+        break;
+    case kEnd:
+        pos = end;
+        if(delta < 0) {
+            UTF_BACK_N(text, begin, pos, -delta);
+        }
+        break;
+    default:
+        break;
+    }
+
+    return pos;
+}
+
+void UCharCharacterIterator::setText(const UChar* newText,
+                                     int32_t      newTextLength) {
+    text = newText;
+    if(newText == 0 || newTextLength < 0) {
+        newTextLength = 0;
+    }
+    end = textLength = newTextLength;
+    pos = begin = 0;
+}
+
+void
+UCharCharacterIterator::getText(UnicodeString& result) {
+    result = UnicodeString(text, textLength);
+}
+
+U_NAMESPACE_END
diff --git a/icu/source/common/ucln.h b/icu/source/common/ucln.h
new file mode 100644
index 0000000..4808e0e
--- /dev/null
+++ b/icu/source/common/ucln.h
@@ -0,0 +1,88 @@
+/*
+******************************************************************************
+*                                                                            *
+* Copyright (C) 2001-2010, International Business Machines                   *
+*                Corporation and others. All Rights Reserved.                *
+*                                                                            *
+******************************************************************************
+*   file name:  ucln_cmn.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2001July05
+*   created by: George Rhoten
+*/
+
+#ifndef __UCLN_H__
+#define __UCLN_H__
+
+#include "unicode/utypes.h"
+
+/** These are the functions used to register a library's memory cleanup
+ * functions.  Each library should define a single library register function
+ * to call this API.  In the i18n library, it is ucln_i18n_registerCleanup().
+ *
+ * None of the cleanup functions should use a mutex to clean up an API's
+ * allocated memory because a cleanup function is not meant to be thread safe,
+ * and plenty of data cannot be reference counted in order to make sure that
+ * no one else needs the allocated data.
+ *
+ * In order to make a cleanup function get called when u_cleanup is called,
+ * You should add your function to the library specific cleanup function.
+ * If the cleanup function is not in the common library, the code that
+ * allocates the memory should call the library specific cleanup function.
+ * For instance, in the i18n library, any memory allocated statically must
+ * call ucln_i18n_registerCleanup() from the ucln_in.h header.  These library
+ * cleanup functions are needed in order to prevent a circular dependency
+ * between the common library and any other library.
+ *
+ * The order of the cleanup is very important.  In general, an API that
+ * depends on a second API should be cleaned up before the second API.
+ * For instance, the default converter in ustring depends upon the converter
+ * API.  So the default converter should be closed before the converter API
+ * has its cache flushed.  This will prevent any memory leaks due to
+ * reference counting.
+ *
+ * Please see common/ucln_cmn.{h,c} and i18n/ucln_in.{h,c} for examples.
+ */
+
+/**
+ * Data Type for cleanup function selector. These roughly correspond to libraries.
+ */
+typedef enum ECleanupLibraryType {
+    UCLN_START = -1,
+    UCLN_UPLUG,     /* ICU plugins */
+    UCLN_CUSTOM,    /* Custom is for anyone else. */
+    UCLN_CTESTFW,
+    UCLN_LAYOUTEX,
+    UCLN_LAYOUT,
+    UCLN_IO,
+    UCLN_I18N,
+    UCLN_COMMON /* This must be the last one to cleanup. */
+} ECleanupLibraryType;
+
+/**
+ * Data type for cleanup function pointer
+ */
+U_CDECL_BEGIN
+typedef UBool U_CALLCONV cleanupFunc(void);
+U_CDECL_END
+
+/**
+ * Register a cleanup function
+ * @param type which library to register for.
+ * @param func the function pointer
+ */
+U_CAPI void U_EXPORT2 ucln_registerCleanup(ECleanupLibraryType type,
+                                           cleanupFunc *func);
+
+/**
+ * Request cleanup for one specific library.
+ * Not thread safe.
+ * Calling this with UCLN_COMMON just calls u_cleanup();
+ * @param type which library to cleanup
+ */
+U_CAPI void U_EXPORT2 ucln_cleanupOne(ECleanupLibraryType type);
+
+#endif
diff --git a/icu/source/common/ucln_cmn.c b/icu/source/common/ucln_cmn.c
new file mode 100644
index 0000000..498c15e
--- /dev/null
+++ b/icu/source/common/ucln_cmn.c
@@ -0,0 +1,112 @@
+/*
+******************************************************************************
+* Copyright (C) 2001-2010, International Business Machines
+*                Corporation and others. All Rights Reserved.
+******************************************************************************
+*   file name:  ucln_cmn.c
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2001July05
+*   created by: George Rhoten
+*/
+
+#include "unicode/utypes.h"
+#include "unicode/uclean.h"
+#include "utracimp.h"
+#include "ustr_imp.h"
+#include "ucln_cmn.h"
+#include "umutex.h"
+#include "ucln.h"
+#include "cmemory.h"
+#include "uassert.h"
+
+/**  Auto-client for UCLN_COMMON **/
+#define UCLN_TYPE UCLN_COMMON
+#include "ucln_imp.h"
+
+static cleanupFunc *gCommonCleanupFunctions[UCLN_COMMON_COUNT];
+static cleanupFunc *gLibCleanupFunctions[UCLN_COMMON];
+
+
+/* Enables debugging information about when a library is cleaned up. */
+#ifndef UCLN_DEBUG_CLEANUP
+#define UCLN_DEBUG_CLEANUP 0
+#endif
+
+
+#if defined(UCLN_DEBUG_CLEANUP)
+#include <stdio.h>
+#endif
+
+static void ucln_cleanup_internal(ECleanupLibraryType libType) 
+{
+    if (gLibCleanupFunctions[libType])
+    {
+        gLibCleanupFunctions[libType]();
+        gLibCleanupFunctions[libType] = NULL;
+    }
+}
+
+U_CAPI void U_EXPORT2 ucln_cleanupOne(ECleanupLibraryType libType)
+{
+    if(libType==UCLN_COMMON) {
+#if UCLN_DEBUG_CLEANUP
+        fprintf(stderr, "Cleaning up: UCLN_COMMON with u_cleanup, type %d\n", (int)libType);
+#endif
+        u_cleanup();
+    } else {
+#if UCLN_DEBUG_CLEANUP
+        fprintf(stderr, "Cleaning up: using ucln_cleanup_internal, type %d\n", (int)libType);
+#endif
+        ucln_cleanup_internal(libType);
+    }
+}
+
+
+U_CFUNC void
+ucln_common_registerCleanup(ECleanupCommonType type,
+                            cleanupFunc *func)
+{
+    U_ASSERT(UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT);
+    if (UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT)
+    {
+        gCommonCleanupFunctions[type] = func;
+    }
+#if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL))
+    ucln_registerAutomaticCleanup();
+#endif
+}
+
+U_CAPI void U_EXPORT2
+ucln_registerCleanup(ECleanupLibraryType type,
+                     cleanupFunc *func)
+{
+    U_ASSERT(UCLN_START < type && type < UCLN_COMMON);
+    if (UCLN_START < type && type < UCLN_COMMON)
+    {
+        gLibCleanupFunctions[type] = func;
+    }
+}
+
+U_CFUNC UBool ucln_lib_cleanup(void) {
+    ECleanupLibraryType libType = UCLN_START;
+    ECleanupCommonType commonFunc = UCLN_COMMON_START;
+
+    for (libType++; libType<UCLN_COMMON; libType++) {
+        ucln_cleanup_internal(libType);
+    }
+
+    for (commonFunc++; commonFunc<UCLN_COMMON_COUNT; commonFunc++) {
+        if (gCommonCleanupFunctions[commonFunc])
+        {
+            gCommonCleanupFunctions[commonFunc]();
+            gCommonCleanupFunctions[commonFunc] = NULL;
+        }
+    }
+#if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL))
+    ucln_unRegisterAutomaticCleanup();
+#endif
+    return TRUE;
+}
diff --git a/icu/source/common/ucln_cmn.h b/icu/source/common/ucln_cmn.h
new file mode 100644
index 0000000..18998dd
--- /dev/null
+++ b/icu/source/common/ucln_cmn.h
@@ -0,0 +1,64 @@
+/*
+******************************************************************************
+*                                                                            *
+* Copyright (C) 2001-2010, International Business Machines                   *
+*                Corporation and others. All Rights Reserved.                *
+*                                                                            *
+******************************************************************************
+*   file name:  ucln_cmn.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2001July05
+*   created by: George Rhoten
+*/
+
+#ifndef __UCLN_CMN_H__
+#define __UCLN_CMN_H__
+
+#include "unicode/utypes.h"
+#include "ucln.h"
+
+/* These are the cleanup functions for various APIs. */
+/* @return true if cleanup complete successfully.*/
+U_CFUNC UBool umtx_cleanup(void);
+
+U_CFUNC UBool utrace_cleanup(void);
+
+U_CFUNC UBool ucln_lib_cleanup(void);
+
+/*
+Please keep the order of enums declared in same order
+as the cleanup functions are suppose to be called. */
+typedef enum ECleanupCommonType {
+    UCLN_COMMON_START = -1,
+    UCLN_COMMON_USPREP,
+    UCLN_COMMON_BREAKITERATOR,
+    UCLN_COMMON_BREAKITERATOR_DICT,
+    UCLN_COMMON_SERVICE,
+    UCLN_COMMON_URES,
+    UCLN_COMMON_LOCALE,
+    UCLN_COMMON_LOCALE_AVAILABLE,
+    UCLN_COMMON_ULOC,
+    UCLN_COMMON_NORMALIZER2,
+    UCLN_COMMON_USET,
+    UCLN_COMMON_UNAMES,
+    UCLN_COMMON_PNAME,
+    UCLN_COMMON_UPROPS,
+    UCLN_COMMON_UBIDI,
+    UCLN_COMMON_UCASE,
+    UCLN_COMMON_UCHAR,
+    UCLN_COMMON_UCNV,
+    UCLN_COMMON_UCNV_IO,
+    UCLN_COMMON_UDATA,
+    UCLN_COMMON_PUTIL,
+    UCLN_COMMON_COUNT /* This must be last */
+} ECleanupCommonType;
+
+/* Main library cleanup registration function. */
+/* See common/ucln.h for details on adding a cleanup function. */
+U_CFUNC void U_EXPORT2 ucln_common_registerCleanup(ECleanupCommonType type,
+                                                   cleanupFunc *func);
+
+#endif
diff --git a/icu/source/common/ucln_imp.h b/icu/source/common/ucln_imp.h
new file mode 100644
index 0000000..9268729
--- /dev/null
+++ b/icu/source/common/ucln_imp.h
@@ -0,0 +1,171 @@
+/*
+******************************************************************************
+*                                                                            *
+* Copyright (C) 2009, International Business Machines                   *
+*                Corporation and others. All Rights Reserved.                *
+*                                                                            *
+******************************************************************************
+*   file name:  ucln_imp.h
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   This file contains the platform specific implementation of per-library cleanup.
+*
+*/
+
+
+#ifndef __UCLN_IMP_H__
+#define __UCLN_IMP_H__
+
+#include "ucln.h"
+#include <stdlib.h>
+
+/**
+ * Auto cleanup of ICU libraries
+ * There are several methods in per library cleanup of icu libraries:
+ * 1) Compiler/Platform based cleanup:
+ *   a) Windows MSVC uses DllMain()
+ *   b) GCC uses destructor function attribute
+ *   c) Sun Studio, AIX VA, and HP-UX aCC uses a linker option to set the exit function
+ * 2) Using atexit()
+ * 3) Implementing own automatic cleanup functions
+ *
+ * For option 1, ensure that UCLN_NO_AUTO_CLEANUP is set to 0 by using --enable-auto-cleanup
+ * configure option or by setting UCLN_NO_AUTO_CLEANUP to 0 in pwin32.h (For Visual Studio
+ * solution file builds)
+ * For option 2, follow option 1 and also define UCLN_AUTO_ATEXIT
+ * For option 3, follow option 1 and also define UCLN_AUTO_LOCAL (see below for more information)
+ */
+
+#if !UCLN_NO_AUTO_CLEANUP
+
+/*
+ * The following declarations are for when UCLN_AUTO_LOCAL or UCLN_AUTO_ATEXIT
+ * are defined. They are commented out because they are static and will be defined
+ * later. The information is still here to provide some guidance for the developer
+ * who chooses to use UCLN_AUTO_LOCAL.
+ */
+/**
+ * Give the library an opportunity to register an automatic cleanup.
+ * This may be called more than once.
+ */
+/*static void ucln_registerAutomaticCleanup();*/
+/**
+ * Unregister an automatic cleanup, if possible. Called from cleanup.
+ */
+/*static void ucln_unRegisterAutomaticCleanup();*/
+
+/* ------------ automatic cleanup: registration. Choose ONE ------- */
+#if defined(UCLN_AUTO_LOCAL)
+/* To use:
+ *  1. define UCLN_AUTO_LOCAL,
+ *  2. create ucln_local_hook.c containing implementations of
+ *           static void ucln_registerAutomaticCleanup()
+ *           static void ucln_unRegisterAutomaticCleanup()
+ */
+#include "ucln_local_hook.c"
+
+#elif defined(UCLN_AUTO_ATEXIT)
+/*
+ * Use the ANSI C 'atexit' function. Note that this mechanism does not
+ * guarantee the order of cleanup relative to other users of ICU!
+ */
+static UBool gAutoCleanRegistered = FALSE;
+
+static void ucln_atexit_handler()
+{
+    ucln_cleanupOne(UCLN_TYPE);
+}
+
+static void ucln_registerAutomaticCleanup()
+{
+    if(!gAutoCleanRegistered) {
+        gAutoCleanRegistered = TRUE;
+        atexit(&ucln_atexit_handler);
+    }
+}
+
+static void ucln_unRegisterAutomaticCleanup () {
+}
+/* ------------end of automatic cleanup: registration. ------- */
+
+#elif defined (UCLN_FINI)
+/**
+ * If UCLN_FINI is defined, it is the (versioned, etc) name of a cleanup
+ * entrypoint. Add a stub to call ucln_cleanupOne
+ * Used on AIX, Solaris, and HP-UX
+ */
+U_CAPI void U_EXPORT2 UCLN_FINI (void);
+
+U_CAPI void U_EXPORT2 UCLN_FINI ()
+{
+    /* This function must be defined, if UCLN_FINI is defined, else link error. */
+     ucln_cleanupOne(UCLN_TYPE);
+}
+#elif defined(__GNUC__)
+/* GCC - use __attribute((destructor)) */
+static void ucln_destructor()   __attribute__((destructor)) ;
+
+static void ucln_destructor() 
+{
+    ucln_cleanupOne(UCLN_TYPE);
+}
+
+/* Windows: DllMain */
+#elif defined (U_WINDOWS)
+/* 
+ * ICU's own DllMain.
+ */
+
+/* these are from putil.c */
+/* READ READ READ READ!    Are you getting compilation errors from windows.h?
+          Any source file which includes this (ucln_imp.h) header MUST 
+          be defined with language extensions ON. */
+#   define WIN32_LEAN_AND_MEAN
+#   define VC_EXTRALEAN
+#   define NOUSER
+#   define NOSERVICE
+#   define NOIME
+#   define NOMCX
+#   include <windows.h>
+/*
+ * This is a stub DllMain function with icu specific process handling code.
+ */
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+    BOOL status = TRUE;
+
+    switch(fdwReason) {
+        case DLL_PROCESS_ATTACH:
+             /* ICU does not trap process attach, but must pass these through properly. */
+            /* ICU specific process attach could go here */
+            break;
+
+        case DLL_PROCESS_DETACH:
+            /* Here is the one we actually care about. */
+
+            ucln_cleanupOne(UCLN_TYPE);
+
+            break;
+
+        case DLL_THREAD_ATTACH:
+            /* ICU does not trap thread attach, but must pass these through properly. */
+            /* ICU specific thread attach could go here */
+            break;
+
+        case DLL_THREAD_DETACH:
+            /* ICU does not trap thread detach, but must pass these through properly. */
+            /* ICU specific thread detach could go here */
+            break;
+
+    }
+    return status;
+}
+#endif
+
+#endif /* UCLN_NO_AUTO_CLEANUP */
+
+#else
+#error This file can only be included once.
+#endif
diff --git a/icu/source/common/ucmndata.c b/icu/source/common/ucmndata.c
new file mode 100644
index 0000000..61262f7
--- /dev/null
+++ b/icu/source/common/ucmndata.c
@@ -0,0 +1,300 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1999-2008, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************/
+
+
+/*------------------------------------------------------------------------------
+ *
+ *   UCommonData   An abstract interface for dealing with ICU Common Data Files.
+ *                 ICU Common Data Files are a grouping of a number of individual
+ *                 data items (resources, converters, tables, anything) into a
+ *                 single file or dll.  The combined format includes a table of
+ *                 contents for locating the individual items by name.
+ *
+ *                 Two formats for the table of contents are supported, which is
+ *                 why there is an abstract inteface involved.
+ *
+ */
+
+#include "unicode/utypes.h"
+#include "unicode/udata.h"
+#include "cstring.h"
+#include "ucmndata.h"
+#include "udatamem.h"
+
+#if defined(UDATA_DEBUG) || defined(UDATA_DEBUG_DUMP)
+#   include <stdio.h>
+#endif
+
+U_CFUNC uint16_t
+udata_getHeaderSize(const DataHeader *udh) {
+    if(udh==NULL) {
+        return 0;
+    } else if(udh->info.isBigEndian==U_IS_BIG_ENDIAN) {
+        /* same endianness */
+        return udh->dataHeader.headerSize;
+    } else {
+        /* opposite endianness */
+        uint16_t x=udh->dataHeader.headerSize;
+        return (uint16_t)((x<<8)|(x>>8));
+    }
+}
+
+U_CFUNC uint16_t
+udata_getInfoSize(const UDataInfo *info) {
+    if(info==NULL) {
+        return 0;
+    } else if(info->isBigEndian==U_IS_BIG_ENDIAN) {
+        /* same endianness */
+        return info->size;
+    } else {
+        /* opposite endianness */
+        uint16_t x=info->size;
+        return (uint16_t)((x<<8)|(x>>8));
+    }
+}
+
+/*-----------------------------------------------------------------------------*
+ *                                                                             *
+ *  Pointer TOCs.   TODO: This form of table-of-contents should be removed     *
+ *                  because DLLs must be relocated on loading to correct the   *
+ *                  pointer values and this operation makes shared memory      *
+ *                  mapping of the data much less likely to work.              *
+ *                                                                             *
+ *-----------------------------------------------------------------------------*/
+typedef struct {
+    const char       *entryName;
+    const DataHeader *pHeader;
+} PointerTOCEntry;
+
+
+typedef struct  {
+    uint32_t          count;
+    uint32_t          reserved;
+    PointerTOCEntry   entry[2];   /* Actual size is from count. */
+}  PointerTOC;
+
+
+/* definition of OffsetTOC struct types moved to ucmndata.h */
+
+/*-----------------------------------------------------------------------------*
+ *                                                                             *
+ *    entry point lookup implementations                                       *
+ *                                                                             *
+ *-----------------------------------------------------------------------------*/
+static uint32_t offsetTOCEntryCount(const UDataMemory *pData) {
+    int32_t          retVal=0;
+    const UDataOffsetTOC *toc = (UDataOffsetTOC *)pData->toc;
+    if (toc != NULL) {
+        retVal = toc->count;
+    }
+    return retVal;
+}
+
+
+static const DataHeader *
+offsetTOCLookupFn(const UDataMemory *pData,
+                  const char *tocEntryName,
+                  int32_t *pLength,
+                  UErrorCode *pErrorCode) {
+    const UDataOffsetTOC  *toc = (UDataOffsetTOC *)pData->toc;
+    if(toc!=NULL) {
+        const char *base=(const char *)toc;
+        uint32_t start, limit, number, lastNumber;
+        int32_t strResult;
+        const UDataOffsetTOCEntry *entry;
+
+        /* perform a binary search for the data in the common data's table of contents */
+#if defined (UDATA_DEBUG_DUMP)
+        /* list the contents of the TOC each time .. not recommended */
+        for(start=0;start<toc->count;start++) {
+          fprintf(stderr, "\tx%d: %s\n", start, &base[toc->entry[start].nameOffset]);
+        }
+#endif
+
+        start=0;
+        limit=toc->count;         /* number of names in this table of contents */
+        lastNumber=limit;
+        entry=toc->entry;
+        for (;;) {
+            number = (start+limit)/2;
+            if (lastNumber == number) { /* Have we moved? */
+                break;  /* We haven't moved, and it wasn't found; */
+                        /* or the empty stub common data library was used during build. */
+            }
+            lastNumber = number;
+            strResult = uprv_strcmp(tocEntryName, base+entry[number].nameOffset);
+            if(strResult<0) {
+                limit=number;
+            } else if (strResult>0) {
+                start=number;
+            }
+            else {
+                /* found it */
+#ifdef UDATA_DEBUG
+                fprintf(stderr, "%s: Found.\n", tocEntryName);
+#endif
+                entry += number; /* Alias the entry to the current entry. */
+                if((number+1) < toc->count) {
+                    *pLength = (int32_t)(entry[1].dataOffset - entry->dataOffset);
+                } else {
+                    *pLength = -1;
+                }
+                return (const DataHeader *)(base+entry->dataOffset);
+            }
+        }
+#ifdef UDATA_DEBUG
+        fprintf(stderr, "%s: Not found.\n", tocEntryName);
+#endif
+        return NULL;
+    } else {
+#ifdef UDATA_DEBUG
+        fprintf(stderr, "returning header\n");
+#endif
+
+        return pData->pHeader;
+    }
+}
+
+
+static uint32_t pointerTOCEntryCount(const UDataMemory *pData) {
+    const PointerTOC *toc = (PointerTOC *)pData->toc;
+    return (uint32_t)((toc != NULL) ? (toc->count) : 0);
+}
+
+
+static const DataHeader *pointerTOCLookupFn(const UDataMemory *pData,
+                   const char *name,
+                   int32_t *pLength,
+                   UErrorCode *pErrorCode) {
+    if(pData->toc!=NULL) {
+        const PointerTOC *toc = (PointerTOC *)pData->toc;
+        uint32_t start, limit, number, lastNumber;
+        int32_t strResult;
+
+#if defined (UDATA_DEBUG_DUMP)
+        /* list the contents of the TOC each time .. not recommended */
+        for(start=0;start<toc->count;start++) {
+            fprintf(stderr, "\tx%d: %s\n", start, toc->entry[start].entryName);
+        }
+#endif
+
+        /* perform a binary search for the data in the common data's table of contents */
+        start=0;
+        limit=toc->count;
+        lastNumber=limit;
+
+        for (;;) {
+            number = (start+limit)/2;
+            if (lastNumber == number) { /* Have we moved? */
+                break;  /* We haven't moved, and it wasn't found, */
+                        /* or the empty stub common data library was used during build. */
+            }
+            lastNumber = number;
+            strResult = uprv_strcmp(name, toc->entry[number].entryName);
+            if(strResult<0) {
+                limit=number;
+            } else if (strResult>0) {
+                start=number;
+            }
+            else {
+                /* found it */
+#ifdef UDATA_DEBUG
+                fprintf(stderr, "%s: Found.\n", toc->entry[number].entryName);
+#endif
+                *pLength=-1;
+                return UDataMemory_normalizeDataPointer(toc->entry[number].pHeader);
+            }
+        }
+#ifdef UDATA_DEBUG
+        fprintf(stderr, "%s: Not found.\n", name);
+#endif
+        return NULL;
+    } else {
+        return pData->pHeader;
+    }
+}
+
+static const commonDataFuncs CmnDFuncs = {offsetTOCLookupFn,  offsetTOCEntryCount};
+static const commonDataFuncs ToCPFuncs = {pointerTOCLookupFn, pointerTOCEntryCount};
+
+
+
+/*----------------------------------------------------------------------*
+ *                                                                      *
+ *  checkCommonData   Validate the format of a common data file.        *
+ *                    Fill in the virtual function ptr based on TOC type *
+ *                    If the data is invalid, close the UDataMemory     *
+ *                    and set the appropriate error code.               *
+ *                                                                      *
+ *----------------------------------------------------------------------*/
+void udata_checkCommonData(UDataMemory *udm, UErrorCode *err) {
+    if (U_FAILURE(*err)) {
+        return;
+    }
+
+    if(!(udm->pHeader->dataHeader.magic1==0xda &&
+        udm->pHeader->dataHeader.magic2==0x27 &&
+        udm->pHeader->info.isBigEndian==U_IS_BIG_ENDIAN &&
+        udm->pHeader->info.charsetFamily==U_CHARSET_FAMILY)
+        ) {
+        /* header not valid */
+        *err=U_INVALID_FORMAT_ERROR;
+    }
+    else if (udm->pHeader->info.dataFormat[0]==0x43 &&
+        udm->pHeader->info.dataFormat[1]==0x6d &&
+        udm->pHeader->info.dataFormat[2]==0x6e &&
+        udm->pHeader->info.dataFormat[3]==0x44 &&
+        udm->pHeader->info.formatVersion[0]==1
+        ) {
+        /* dataFormat="CmnD" */
+        udm->vFuncs = &CmnDFuncs;
+        udm->toc=(const char *)udm->pHeader+udata_getHeaderSize(udm->pHeader);
+    }
+    else if(udm->pHeader->info.dataFormat[0]==0x54 &&
+        udm->pHeader->info.dataFormat[1]==0x6f &&
+        udm->pHeader->info.dataFormat[2]==0x43 &&
+        udm->pHeader->info.dataFormat[3]==0x50 &&
+        udm->pHeader->info.formatVersion[0]==1
+        ) {
+        /* dataFormat="ToCP" */
+        udm->vFuncs = &ToCPFuncs;
+        udm->toc=(const char *)udm->pHeader+udata_getHeaderSize(udm->pHeader);
+    }
+    else {
+        /* dataFormat not recognized */
+        *err=U_INVALID_FORMAT_ERROR;
+    }
+
+    if (U_FAILURE(*err)) {
+        /* If the data is no good and we memory-mapped it ourselves,
+         *  close the memory mapping so it doesn't leak.  Note that this has
+         *  no effect on non-memory mapped data, other than clearing fields in udm.
+         */
+        udata_close(udm);
+    }
+}
+
+/*
+ * TODO: Add a udata_swapPackageHeader() function that swaps an ICU .dat package
+ * header but not its sub-items.
+ * This function will be needed for automatic runtime swapping.
+ * Sub-items should not be swapped to limit the swapping to the parts of the
+ * package that are actually used.
+ *
+ * Since lengths of items are implicit in the order and offsets of their
+ * ToC entries, and since offsets are relative to the start of the ToC,
+ * a swapped version may need to generate a different data structure
+ * with pointers to the original data items and with their lengths
+ * (-1 for the last one if it is not known), and maybe even pointers to the
+ * swapped versions of the items.
+ * These pointers to swapped versions would establish a cache;
+ * instead, each open data item could simply own the storage for its swapped
+ * data. This fits better with the current design.
+ *
+ * markus 2003sep18 Jitterbug 2235
+ */
diff --git a/icu/source/common/ucmndata.h b/icu/source/common/ucmndata.h
new file mode 100644
index 0000000..9634ed8
--- /dev/null
+++ b/icu/source/common/ucmndata.h
@@ -0,0 +1,109 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1999-2003, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************/
+
+
+/*----------------------------------------------------------------------------------
+ *
+ *   UCommonData   An abstract interface for dealing with ICU Common Data Files.
+ *                 ICU Common Data Files are a grouping of a number of individual
+ *                 data items (resources, converters, tables, anything) into a
+ *                 single file or dll.  The combined format includes a table of
+ *                 contents for locating the individual items by name.
+ *
+ *                 Two formats for the table of contents are supported, which is
+ *                 why there is an abstract inteface involved.
+ *
+ *                 These functions are part of the ICU internal implementation, and
+ *                 are not inteded to be used directly by applications.
+ */
+
+#ifndef __UCMNDATA_H__
+#define __UCMNDATA_H__
+
+#include "unicode/udata.h"
+#include "umapfile.h"
+
+
+#define COMMON_DATA_NAME U_ICUDATA_NAME
+
+typedef struct  {
+    uint16_t    headerSize;
+    uint8_t     magic1;
+    uint8_t     magic2;
+} MappedData;
+
+
+typedef struct  {
+    MappedData  dataHeader;
+    UDataInfo   info;
+} DataHeader;
+
+typedef struct {
+    uint32_t nameOffset;
+    uint32_t dataOffset;
+} UDataOffsetTOCEntry;
+
+typedef struct {
+    uint32_t count;
+    UDataOffsetTOCEntry entry[2];    /* Actual size of array is from count. */
+} UDataOffsetTOC;
+
+/**
+ * Get the header size from a const DataHeader *udh.
+ * Handles opposite-endian data.
+ *
+ * @internal
+ */
+U_CFUNC uint16_t
+udata_getHeaderSize(const DataHeader *udh);
+
+/**
+ * Get the UDataInfo.size from a const UDataInfo *info.
+ * Handles opposite-endian data.
+ *
+ * @internal
+ */
+U_CFUNC uint16_t
+udata_getInfoSize(const UDataInfo *info);
+
+/*
+ *  "Virtual" functions for data lookup.
+ *  To call one, given a UDataMemory *p, the code looks like this:
+ *     p->vFuncs.Lookup(p, tocEntryName, pErrorCode);
+ *          (I sure do wish this was written in C++, not C)
+ */
+
+typedef const DataHeader *
+(* LookupFn)(const UDataMemory *pData,
+             const char *tocEntryName,
+             int32_t *pLength,
+             UErrorCode *pErrorCode);
+
+typedef uint32_t
+(* NumEntriesFn)(const UDataMemory *pData);
+
+typedef struct {
+    LookupFn      Lookup;
+    NumEntriesFn  NumEntries; 
+} commonDataFuncs;
+
+
+/*
+ *  Functions to check whether a UDataMemory refers to memory containing 
+ *     a recognizable header and table of contents a Common Data Format
+ *
+ *     If a valid header and TOC are found,
+ *         set the CommonDataFuncs function dispatch vector in the UDataMemory
+ *             to point to the right functions for the TOC type.
+ *     otherwise
+ *         set an errorcode.
+ */
+void   udata_checkCommonData(UDataMemory *pData, UErrorCode *pErrorCode);
+
+
+#endif
diff --git a/icu/source/common/ucnv.c b/icu/source/common/ucnv.c
new file mode 100644
index 0000000..ed980e8
--- /dev/null
+++ b/icu/source/common/ucnv.c
@@ -0,0 +1,2892 @@
+/*
+******************************************************************************
+*
+*   Copyright (C) 1998-2008, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+*
+******************************************************************************
+*
+*  ucnv.c:
+*  Implements APIs for the ICU's codeset conversion library;
+*  mostly calls through internal functions;
+*  created by Bertrand A. Damiba
+*
+* Modification History:
+*
+*   Date        Name        Description
+*   04/04/99    helena      Fixed internal header inclusion.
+*   05/09/00    helena      Added implementation to handle fallback mappings.
+*   06/20/2000  helena      OS/400 port changes; mostly typecast.
+*/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_CONVERSION
+
+#include "unicode/ustring.h"
+#include "unicode/ucnv.h"
+#include "unicode/ucnv_err.h"
+#include "unicode/uset.h"
+#include "putilimp.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "uassert.h"
+#include "utracimp.h"
+#include "ustr_imp.h"
+#include "ucnv_imp.h"
+#include "ucnv_cnv.h"
+#include "ucnv_bld.h"
+
+/* size of intermediate and preflighting buffers in ucnv_convert() */
+#define CHUNK_SIZE 1024
+
+typedef struct UAmbiguousConverter {
+    const char *name;
+    const UChar variant5c;
+} UAmbiguousConverter;
+
+static const UAmbiguousConverter ambiguousConverters[]={
+    { "ibm-897_P100-1995", 0xa5 },
+    { "ibm-942_P120-1999", 0xa5 },
+    { "ibm-943_P130-1999", 0xa5 },
+    { "ibm-946_P100-1995", 0xa5 },
+    { "ibm-33722_P120-1999", 0xa5 },
+    /*{ "ibm-54191_P100-2006", 0xa5 },*/
+    /*{ "ibm-62383_P100-2007", 0xa5 },*/
+    /*{ "ibm-891_P100-1995", 0x20a9 },*/
+    { "ibm-944_P100-1995", 0x20a9 },
+    { "ibm-949_P110-1999", 0x20a9 },
+    { "ibm-1363_P110-1997", 0x20a9 },
+    { "ISO_2022,locale=ko,version=0", 0x20a9 }
+};
+
+/*Calls through createConverter */
+U_CAPI UConverter* U_EXPORT2
+ucnv_open (const char *name,
+                       UErrorCode * err)
+{
+    UConverter *r;
+
+    if (err == NULL || U_FAILURE (*err)) {
+        return NULL;
+    }
+
+    r =  ucnv_createConverter(NULL, name, err);
+    return r;
+}
+
+U_CAPI UConverter* U_EXPORT2 
+ucnv_openPackage   (const char *packageName, const char *converterName, UErrorCode * err)
+{
+    return ucnv_createConverterFromPackage(packageName, converterName,  err);
+}
+
+/*Extracts the UChar* to a char* and calls through createConverter */
+U_CAPI UConverter*   U_EXPORT2
+ucnv_openU (const UChar * name,
+                         UErrorCode * err)
+{
+    char asciiName[UCNV_MAX_CONVERTER_NAME_LENGTH];
+
+    if (err == NULL || U_FAILURE(*err))
+        return NULL;
+    if (name == NULL)
+        return ucnv_open (NULL, err);
+    if (u_strlen(name) >= UCNV_MAX_CONVERTER_NAME_LENGTH)
+    {
+        *err = U_ILLEGAL_ARGUMENT_ERROR;
+        return NULL;
+    }
+    return ucnv_open(u_austrcpy(asciiName, name), err);
+}
+
+/* Copy the string that is represented by the UConverterPlatform enum
+ * @param platformString An output buffer
+ * @param platform An enum representing a platform
+ * @return the length of the copied string.
+ */
+static int32_t
+ucnv_copyPlatformString(char *platformString, UConverterPlatform pltfrm)
+{
+    switch (pltfrm)
+    {
+    case UCNV_IBM:
+        uprv_strcpy(platformString, "ibm-");
+        return 4;
+    case UCNV_UNKNOWN:
+        break;
+    }
+
+    /* default to empty string */
+    *platformString = 0;
+    return 0;
+}
+
+/*Assumes a $platform-#codepage.$CONVERTER_FILE_EXTENSION scheme and calls
+ *through createConverter*/
+U_CAPI UConverter*   U_EXPORT2
+ucnv_openCCSID (int32_t codepage,
+                UConverterPlatform platform,
+                UErrorCode * err)
+{
+    char myName[UCNV_MAX_CONVERTER_NAME_LENGTH];
+    int32_t myNameLen;
+
+    if (err == NULL || U_FAILURE (*err))
+        return NULL;
+
+    /* ucnv_copyPlatformString could return "ibm-" or "cp" */
+    myNameLen = ucnv_copyPlatformString(myName, platform);
+    T_CString_integerToString(myName + myNameLen, codepage, 10);
+
+    return ucnv_createConverter(NULL, myName, err);
+}
+
+/* Creating a temporary stack-based object that can be used in one thread, 
+and created from a converter that is shared across threads.
+*/
+
+U_CAPI UConverter* U_EXPORT2
+ucnv_safeClone(const UConverter* cnv, void *stackBuffer, int32_t *pBufferSize, UErrorCode *status)
+{
+    UConverter *localConverter, *allocatedConverter;
+    int32_t bufferSizeNeeded;
+    char *stackBufferChars = (char *)stackBuffer;
+    UErrorCode cbErr;
+    UConverterToUnicodeArgs toUArgs = {
+        sizeof(UConverterToUnicodeArgs),
+            TRUE,
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            NULL
+    };
+    UConverterFromUnicodeArgs fromUArgs = {
+        sizeof(UConverterFromUnicodeArgs),
+            TRUE,
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            NULL,
+            NULL
+    };
+
+    UTRACE_ENTRY_OC(UTRACE_UCNV_CLONE);
+
+    if (status == NULL || U_FAILURE(*status)){
+        UTRACE_EXIT_STATUS(status? *status: U_ILLEGAL_ARGUMENT_ERROR);
+        return 0;
+    }
+
+    if (!pBufferSize || !cnv){
+        *status = U_ILLEGAL_ARGUMENT_ERROR;
+        UTRACE_EXIT_STATUS(*status);
+        return 0;
+    }
+
+    UTRACE_DATA3(UTRACE_OPEN_CLOSE, "clone converter %s at %p into stackBuffer %p",
+                                    ucnv_getName(cnv, status), cnv, stackBuffer);
+
+    if (cnv->sharedData->impl->safeClone != NULL) {
+        /* call the custom safeClone function for sizing */
+        bufferSizeNeeded = 0;
+        cnv->sharedData->impl->safeClone(cnv, NULL, &bufferSizeNeeded, status);
+    }
+    else
+    {
+        /* inherent sizing */
+        bufferSizeNeeded = sizeof(UConverter);
+    }
+
+    if (*pBufferSize <= 0){ /* 'preflighting' request - set needed size into *pBufferSize */
+        *pBufferSize = bufferSizeNeeded;
+        UTRACE_EXIT_VALUE(bufferSizeNeeded);
+        return 0;
+    }
+
+
+    /* Pointers on 64-bit platforms need to be aligned
+     * on a 64-bit boundary in memory.
+     */
+    if (U_ALIGNMENT_OFFSET(stackBuffer) != 0) {
+        int32_t offsetUp = (int32_t)U_ALIGNMENT_OFFSET_UP(stackBufferChars);
+        if(*pBufferSize > offsetUp) {
+            *pBufferSize -= offsetUp;
+            stackBufferChars += offsetUp;
+        } else {
+            /* prevent using the stack buffer but keep the size > 0 so that we do not just preflight */
+            *pBufferSize = 1;
+        }
+    }
+
+    stackBuffer = (void *)stackBufferChars;
+    
+    /* Now, see if we must allocate any memory */
+    if (*pBufferSize < bufferSizeNeeded || stackBuffer == NULL)
+    {
+        /* allocate one here...*/
+        localConverter = allocatedConverter = (UConverter *) uprv_malloc (bufferSizeNeeded);
+
+        if(localConverter == NULL) {
+            *status = U_MEMORY_ALLOCATION_ERROR;
+            UTRACE_EXIT_STATUS(*status);
+            return NULL;
+        }
+        
+        if (U_SUCCESS(*status)) {
+            *status = U_SAFECLONE_ALLOCATED_WARNING;
+        }
+        
+        /* record the fact that memory was allocated */
+        *pBufferSize = bufferSizeNeeded;
+    } else {
+        /* just use the stack buffer */
+        localConverter = (UConverter*) stackBuffer;
+        allocatedConverter = NULL;
+    }
+
+    uprv_memset(localConverter, 0, bufferSizeNeeded);
+
+    /* Copy initial state */
+    uprv_memcpy(localConverter, cnv, sizeof(UConverter));
+    localConverter->isCopyLocal = localConverter->isExtraLocal = FALSE;
+
+    /* copy the substitution string */
+    if (cnv->subChars == (uint8_t *)cnv->subUChars) {
+        localConverter->subChars = (uint8_t *)localConverter->subUChars;
+    } else {
+        localConverter->subChars = (uint8_t *)uprv_malloc(UCNV_ERROR_BUFFER_LENGTH * U_SIZEOF_UCHAR);
+        if (localConverter->subChars == NULL) {
+            uprv_free(allocatedConverter);
+            UTRACE_EXIT_STATUS(*status);
+            return NULL;
+        }
+        uprv_memcpy(localConverter->subChars, cnv->subChars, UCNV_ERROR_BUFFER_LENGTH * U_SIZEOF_UCHAR);
+    }
+
+    /* now either call the safeclone fcn or not */
+    if (cnv->sharedData->impl->safeClone != NULL) {
+        /* call the custom safeClone function */
+        localConverter = cnv->sharedData->impl->safeClone(cnv, localConverter, pBufferSize, status);
+    }
+
+    if(localConverter==NULL || U_FAILURE(*status)) {
+        if (allocatedConverter != NULL && allocatedConverter->subChars != (uint8_t *)allocatedConverter->subUChars) {
+            uprv_free(allocatedConverter->subChars);
+        }
+        uprv_free(allocatedConverter);
+        UTRACE_EXIT_STATUS(*status);
+        return NULL;
+    }
+
+    /* increment refcount of shared data if needed */
+    /*
+    Checking whether it's an algorithic converter is okay
+    in multithreaded applications because the value never changes.
+    Don't check referenceCounter for any other value.
+    */
+    if (cnv->sharedData->referenceCounter != ~0) {
+        ucnv_incrementRefCount(cnv->sharedData);
+    }
+
+    if(localConverter == (UConverter*)stackBuffer) {
+        /* we're using user provided data - set to not destroy */
+        localConverter->isCopyLocal = TRUE;
+    }
+
+    /* allow callback functions to handle any memory allocation */
+    toUArgs.converter = fromUArgs.converter = localConverter;
+    cbErr = U_ZERO_ERROR;
+    cnv->fromCharErrorBehaviour(cnv->toUContext, &toUArgs, NULL, 0, UCNV_CLONE, &cbErr);
+    cbErr = U_ZERO_ERROR;
+    cnv->fromUCharErrorBehaviour(cnv->fromUContext, &fromUArgs, NULL, 0, 0, UCNV_CLONE, &cbErr);
+
+    UTRACE_EXIT_PTR_STATUS(localConverter, *status);
+    return localConverter;
+}
+
+
+
+/*Decreases the reference counter in the shared immutable section of the object
+ *and frees the mutable part*/
+
+U_CAPI void  U_EXPORT2
+ucnv_close (UConverter * converter)
+{
+    UErrorCode errorCode = U_ZERO_ERROR;
+
+    UTRACE_ENTRY_OC(UTRACE_UCNV_CLOSE);
+
+    if (converter == NULL)
+    {
+        UTRACE_EXIT();
+        return;
+    }
+
+    UTRACE_DATA3(UTRACE_OPEN_CLOSE, "close converter %s at %p, isCopyLocal=%b",
+        ucnv_getName(converter, &errorCode), converter, converter->isCopyLocal);
+
+    /* In order to speed up the close, only call the callbacks when they have been changed.
+    This performance check will only work when the callbacks are set within a shared library
+    or from user code that statically links this code. */
+    /* first, notify the callback functions that the converter is closed */
+    if (converter->fromCharErrorBehaviour != UCNV_TO_U_DEFAULT_CALLBACK) {
+        UConverterToUnicodeArgs toUArgs = {
+            sizeof(UConverterToUnicodeArgs),
+                TRUE,
+                NULL,
+                NULL,
+                NULL,
+                NULL,
+                NULL,
+                NULL
+        };
+
+        toUArgs.converter = converter;
+        errorCode = U_ZERO_ERROR;
+        converter->fromCharErrorBehaviour(converter->toUContext, &toUArgs, NULL, 0, UCNV_CLOSE, &errorCode);
+    }
+    if (converter->fromUCharErrorBehaviour != UCNV_FROM_U_DEFAULT_CALLBACK) {
+        UConverterFromUnicodeArgs fromUArgs = {
+            sizeof(UConverterFromUnicodeArgs),
+                TRUE,
+                NULL,
+                NULL,
+                NULL,
+                NULL,
+                NULL,
+                NULL
+        };
+        fromUArgs.converter = converter;
+        errorCode = U_ZERO_ERROR;
+        converter->fromUCharErrorBehaviour(converter->fromUContext, &fromUArgs, NULL, 0, 0, UCNV_CLOSE, &errorCode);
+    }
+
+    if (converter->sharedData->impl->close != NULL) {
+        converter->sharedData->impl->close(converter);
+    }
+
+    if (converter->subChars != (uint8_t *)converter->subUChars) {
+        uprv_free(converter->subChars);
+    }
+
+    /*
+    Checking whether it's an algorithic converter is okay
+    in multithreaded applications because the value never changes.
+    Don't check referenceCounter for any other value.
+    */
+    if (converter->sharedData->referenceCounter != ~0) {
+        ucnv_unloadSharedDataIfReady(converter->sharedData);
+    }
+
+    if(!converter->isCopyLocal){
+        uprv_free(converter);
+    }
+
+    UTRACE_EXIT();
+}
+
+/*returns a single Name from the list, will return NULL if out of bounds
+ */
+U_CAPI const char*   U_EXPORT2
+ucnv_getAvailableName (int32_t n)
+{
+    if (0 <= n && n <= 0xffff) {
+        UErrorCode err = U_ZERO_ERROR;
+        const char *name = ucnv_bld_getAvailableConverter((uint16_t)n, &err);
+        if (U_SUCCESS(err)) {
+            return name;
+        }
+    }
+    return NULL;
+}
+
+U_CAPI int32_t   U_EXPORT2
+ucnv_countAvailable ()
+{
+    UErrorCode err = U_ZERO_ERROR;
+    return ucnv_bld_countAvailableConverters(&err);
+}
+
+U_CAPI void    U_EXPORT2
+ucnv_getSubstChars (const UConverter * converter,
+                    char *mySubChar,
+                    int8_t * len,
+                    UErrorCode * err)
+{
+    if (U_FAILURE (*err))
+        return;
+
+    if (converter->subCharLen <= 0) {
+        /* Unicode string or empty string from ucnv_setSubstString(). */
+        *len = 0;
+        return;
+    }
+
+    if (*len < converter->subCharLen) /*not enough space in subChars */
+    {
+        *err = U_INDEX_OUTOFBOUNDS_ERROR;
+        return;
+    }
+
+    uprv_memcpy (mySubChar, converter->subChars, converter->subCharLen);   /*fills in the subchars */
+    *len = converter->subCharLen; /*store # of bytes copied to buffer */
+}
+
+U_CAPI void    U_EXPORT2
+ucnv_setSubstChars (UConverter * converter,
+                    const char *mySubChar,
+                    int8_t len,
+                    UErrorCode * err)
+{
+    if (U_FAILURE (*err))
+        return;
+    
+    /*Makes sure that the subChar is within the codepages char length boundaries */
+    if ((len > converter->sharedData->staticData->maxBytesPerChar)
+     || (len < converter->sharedData->staticData->minBytesPerChar))
+    {
+        *err = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    
+    uprv_memcpy (converter->subChars, mySubChar, len); /*copies the subchars */
+    converter->subCharLen = len;  /*sets the new len */
+
+    /*
+    * There is currently (2001Feb) no separate API to set/get subChar1.
+    * In order to always have subChar written after it is explicitly set,
+    * we set subChar1 to 0.
+    */
+    converter->subChar1 = 0;
+    
+    return;
+}
+
+U_CAPI void U_EXPORT2
+ucnv_setSubstString(UConverter *cnv,
+                    const UChar *s,
+                    int32_t length,
+                    UErrorCode *err) {
+    UAlignedMemory cloneBuffer[U_CNV_SAFECLONE_BUFFERSIZE / sizeof(UAlignedMemory) + 1];
+    char chars[UCNV_ERROR_BUFFER_LENGTH];
+
+    UConverter *clone;
+    uint8_t *subChars;
+    int32_t cloneSize, length8;
+
+    /* Let the following functions check all arguments. */
+    cloneSize = sizeof(cloneBuffer);
+    clone = ucnv_safeClone(cnv, cloneBuffer, &cloneSize, err);
+    ucnv_setFromUCallBack(clone, UCNV_FROM_U_CALLBACK_STOP, NULL, NULL, NULL, err);
+    length8 = ucnv_fromUChars(clone, chars, (int32_t)sizeof(chars), s, length, err);
+    ucnv_close(clone);
+    if (U_FAILURE(*err)) {
+        return;
+    }
+
+    if (cnv->sharedData->impl->writeSub == NULL
+#if !UCONFIG_NO_LEGACY_CONVERSION
+        || (cnv->sharedData->staticData->conversionType == UCNV_MBCS &&
+         ucnv_MBCSGetType(cnv) != UCNV_EBCDIC_STATEFUL)
+#endif
+    ) {
+        /* The converter is not stateful. Store the charset bytes as a fixed string. */
+        subChars = (uint8_t *)chars;
+    } else {
+        /*
+         * The converter has a non-default writeSub() function, indicating
+         * that it is stateful.
+         * Store the Unicode string for on-the-fly conversion for correct
+         * state handling.
+         */
+        if (length > UCNV_ERROR_BUFFER_LENGTH) {
+            /*
+             * Should not occur. The converter should output at least one byte
+             * per UChar, which means that ucnv_fromUChars() should catch all
+             * overflows.
+             */
+            *err = U_BUFFER_OVERFLOW_ERROR;
+            return;
+        }
+        subChars = (uint8_t *)s;
+        if (length < 0) {
+            length = u_strlen(s);
+        }
+        length8 = length * U_SIZEOF_UCHAR;
+    }
+
+    /*
+     * For storing the substitution string, select either the small buffer inside
+     * UConverter or allocate a subChars buffer.
+     */
+    if (length8 > UCNV_MAX_SUBCHAR_LEN) {
+        /* Use a separate buffer for the string. Outside UConverter to not make it too large. */
+        if (cnv->subChars == (uint8_t *)cnv->subUChars) {
+            /* Allocate a new buffer for the string. */
+            cnv->subChars = (uint8_t *)uprv_malloc(UCNV_ERROR_BUFFER_LENGTH * U_SIZEOF_UCHAR);
+            if (cnv->subChars == NULL) {
+                cnv->subChars = (uint8_t *)cnv->subUChars;
+                *err = U_MEMORY_ALLOCATION_ERROR;
+                return;
+            }
+            uprv_memset(cnv->subChars, 0, UCNV_ERROR_BUFFER_LENGTH * U_SIZEOF_UCHAR);
+        }
+    }
+
+    /* Copy the substitution string into the UConverter or its subChars buffer. */
+    if (length8 == 0) {
+        cnv->subCharLen = 0;
+    } else {
+        uprv_memcpy(cnv->subChars, subChars, length8);
+        if (subChars == (uint8_t *)chars) {
+            cnv->subCharLen = (int8_t)length8;
+        } else /* subChars == s */ {
+            cnv->subCharLen = (int8_t)-length;
+        }
+    }
+
+    /* See comment in ucnv_setSubstChars(). */
+    cnv->subChar1 = 0;
+}
+
+/*resets the internal states of a converter
+ *goal : have the same behaviour than a freshly created converter
+ */
+static void _reset(UConverter *converter, UConverterResetChoice choice,
+                   UBool callCallback) {
+    if(converter == NULL) {
+        return;
+    }
+
+    if(callCallback) {
+        /* first, notify the callback functions that the converter is reset */
+        UErrorCode errorCode;
+
+        if(choice<=UCNV_RESET_TO_UNICODE && converter->fromCharErrorBehaviour != UCNV_TO_U_DEFAULT_CALLBACK) {
+            UConverterToUnicodeArgs toUArgs = {
+                sizeof(UConverterToUnicodeArgs),
+                TRUE,
+                NULL,
+                NULL,
+                NULL,
+                NULL,
+                NULL,
+                NULL
+            };
+            toUArgs.converter = converter;
+            errorCode = U_ZERO_ERROR;
+            converter->fromCharErrorBehaviour(converter->toUContext, &toUArgs, NULL, 0, UCNV_RESET, &errorCode);
+        }
+        if(choice!=UCNV_RESET_TO_UNICODE && converter->fromUCharErrorBehaviour != UCNV_FROM_U_DEFAULT_CALLBACK) {
+            UConverterFromUnicodeArgs fromUArgs = {
+                sizeof(UConverterFromUnicodeArgs),
+                TRUE,
+                NULL,
+                NULL,
+                NULL,
+                NULL,
+                NULL,
+                NULL
+            };
+            fromUArgs.converter = converter;
+            errorCode = U_ZERO_ERROR;
+            converter->fromUCharErrorBehaviour(converter->fromUContext, &fromUArgs, NULL, 0, 0, UCNV_RESET, &errorCode);
+        }
+    }
+
+    /* now reset the converter itself */
+    if(choice<=UCNV_RESET_TO_UNICODE) {
+        converter->toUnicodeStatus = converter->sharedData->toUnicodeStatus;
+        converter->mode = 0;
+        converter->toULength = 0;
+        converter->invalidCharLength = converter->UCharErrorBufferLength = 0;
+        converter->preToULength = 0;
+    }
+    if(choice!=UCNV_RESET_TO_UNICODE) {
+        converter->fromUnicodeStatus = 0;
+        converter->fromUChar32 = 0;
+        converter->invalidUCharLength = converter->charErrorBufferLength = 0;
+        converter->preFromUFirstCP = U_SENTINEL;
+        converter->preFromULength = 0;
+    }
+
+    if (converter->sharedData->impl->reset != NULL) {
+        /* call the custom reset function */
+        converter->sharedData->impl->reset(converter, choice);
+    }
+}
+
+U_CAPI void  U_EXPORT2
+ucnv_reset(UConverter *converter)
+{
+    _reset(converter, UCNV_RESET_BOTH, TRUE);
+}
+
+U_CAPI void  U_EXPORT2
+ucnv_resetToUnicode(UConverter *converter)
+{
+    _reset(converter, UCNV_RESET_TO_UNICODE, TRUE);
+}
+
+U_CAPI void  U_EXPORT2
+ucnv_resetFromUnicode(UConverter *converter)
+{
+    _reset(converter, UCNV_RESET_FROM_UNICODE, TRUE);
+}
+
+U_CAPI int8_t   U_EXPORT2
+ucnv_getMaxCharSize (const UConverter * converter)
+{
+    return converter->maxBytesPerUChar;
+}
+
+
+U_CAPI int8_t   U_EXPORT2
+ucnv_getMinCharSize (const UConverter * converter)
+{
+    return converter->sharedData->staticData->minBytesPerChar;
+}
+
+U_CAPI const char*   U_EXPORT2
+ucnv_getName (const UConverter * converter, UErrorCode * err)
+     
+{
+    if (U_FAILURE (*err))
+        return NULL;
+    if(converter->sharedData->impl->getName){
+        const char* temp= converter->sharedData->impl->getName(converter);
+        if(temp)
+            return temp;
+    }
+    return converter->sharedData->staticData->name;
+}
+
+U_CAPI int32_t U_EXPORT2
+ucnv_getCCSID(const UConverter * converter,
+              UErrorCode * err)
+{
+    int32_t ccsid;
+    if (U_FAILURE (*err))
+        return -1;
+
+    ccsid = converter->sharedData->staticData->codepage;
+    if (ccsid == 0) {
+        /* Rare case. This is for cases like gb18030,
+        which doesn't have an IBM cannonical name, but does have an IBM alias. */
+        const char *standardName = ucnv_getStandardName(ucnv_getName(converter, err), "IBM", err);
+        if (U_SUCCESS(*err) && standardName) {
+            const char *ccsidStr = uprv_strchr(standardName, '-');
+            if (ccsidStr) {
+                ccsid = (int32_t)atol(ccsidStr+1);  /* +1 to skip '-' */
+            }
+        }
+    }
+    return ccsid;
+}
+
+
+U_CAPI UConverterPlatform   U_EXPORT2
+ucnv_getPlatform (const UConverter * converter,
+                                      UErrorCode * err)
+{
+    if (U_FAILURE (*err))
+        return UCNV_UNKNOWN;
+
+    return (UConverterPlatform)converter->sharedData->staticData->platform;
+}
+
+U_CAPI void U_EXPORT2
+    ucnv_getToUCallBack (const UConverter * converter,
+                         UConverterToUCallback *action,
+                         const void **context)
+{
+    *action = converter->fromCharErrorBehaviour;
+    *context = converter->toUContext;
+}
+
+U_CAPI void U_EXPORT2
+    ucnv_getFromUCallBack (const UConverter * converter,
+                           UConverterFromUCallback *action,
+                           const void **context)
+{
+    *action = converter->fromUCharErrorBehaviour;
+    *context = converter->fromUContext;
+}
+
+U_CAPI void    U_EXPORT2
+ucnv_setToUCallBack (UConverter * converter,
+                            UConverterToUCallback newAction,
+                            const void* newContext,
+                            UConverterToUCallback *oldAction,
+                            const void** oldContext,
+                            UErrorCode * err)
+{
+    if (U_FAILURE (*err))
+        return;
+    if (oldAction) *oldAction = converter->fromCharErrorBehaviour;
+    converter->fromCharErrorBehaviour = newAction;
+    if (oldContext) *oldContext = converter->toUContext;
+    converter->toUContext = newContext;
+}
+
+U_CAPI void  U_EXPORT2
+ucnv_setFromUCallBack (UConverter * converter,
+                            UConverterFromUCallback newAction,
+                            const void* newContext,
+                            UConverterFromUCallback *oldAction,
+                            const void** oldContext,
+                            UErrorCode * err)
+{
+    if (U_FAILURE (*err))
+        return;
+    if (oldAction) *oldAction = converter->fromUCharErrorBehaviour;
+    converter->fromUCharErrorBehaviour = newAction;
+    if (oldContext) *oldContext = converter->fromUContext;
+    converter->fromUContext = newContext;
+}
+
+static void
+_updateOffsets(int32_t *offsets, int32_t length,
+               int32_t sourceIndex, int32_t errorInputLength) {
+    int32_t *limit;
+    int32_t delta, offset;
+
+    if(sourceIndex>=0) {
+        /*
+         * adjust each offset by adding the previous sourceIndex
+         * minus the length of the input sequence that caused an
+         * error, if any
+         */
+        delta=sourceIndex-errorInputLength;
+    } else {
+        /*
+         * set each offset to -1 because this conversion function
+         * does not handle offsets
+         */
+        delta=-1;
+    }
+
+    limit=offsets+length;
+    if(delta==0) {
+        /* most common case, nothing to do */
+    } else if(delta>0) {
+        /* add the delta to each offset (but not if the offset is <0) */
+        while(offsets<limit) {
+            offset=*offsets;
+            if(offset>=0) {
+                *offsets=offset+delta;
+            }
+            ++offsets;
+        }
+    } else /* delta<0 */ {
+        /*
+         * set each offset to -1 because this conversion function
+         * does not handle offsets
+         * or the error input sequence started in a previous buffer
+         */
+        while(offsets<limit) {
+            *offsets++=-1;
+        }
+    }
+}
+
+/* ucnv_fromUnicode --------------------------------------------------------- */
+
+/*
+ * Implementation note for m:n conversions
+ *
+ * While collecting source units to find the longest match for m:n conversion,
+ * some source units may need to be stored for a partial match.
+ * When a second buffer does not yield a match on all of the previously stored
+ * source units, then they must be "replayed", i.e., fed back into the converter.
+ *
+ * The code relies on the fact that replaying will not nest -
+ * converting a replay buffer will not result in a replay.
+ * This is because a replay is necessary only after the _continuation_ of a
+ * partial match failed, but a replay buffer is converted as a whole.
+ * It may result in some of its units being stored again for a partial match,
+ * but there will not be a continuation _during_ the replay which could fail.
+ *
+ * It is conceivable that a callback function could call the converter
+ * recursively in a way that causes another replay to be stored, but that
+ * would be an error in the callback function.
+ * Such violations will cause assertion failures in a debug build,
+ * and wrong output, but they will not cause a crash.
+ */
+
+static void
+_fromUnicodeWithCallback(UConverterFromUnicodeArgs *pArgs, UErrorCode *err) {
+    UConverterFromUnicode fromUnicode;
+    UConverter *cnv;
+    const UChar *s;
+    char *t;
+    int32_t *offsets;
+    int32_t sourceIndex;
+    int32_t errorInputLength;
+    UBool converterSawEndOfInput, calledCallback;
+
+    /* variables for m:n conversion */
+    UChar replay[UCNV_EXT_MAX_UCHARS];
+    const UChar *realSource, *realSourceLimit;
+    int32_t realSourceIndex;
+    UBool realFlush;
+
+    cnv=pArgs->converter;
+    s=pArgs->source;
+    t=pArgs->target;
+    offsets=pArgs->offsets;
+
+    /* get the converter implementation function */
+    sourceIndex=0;
+    if(offsets==NULL) {
+        fromUnicode=cnv->sharedData->impl->fromUnicode;
+    } else {
+        fromUnicode=cnv->sharedData->impl->fromUnicodeWithOffsets;
+        if(fromUnicode==NULL) {
+            /* there is no WithOffsets implementation */
+            fromUnicode=cnv->sharedData->impl->fromUnicode;
+            /* we will write -1 for each offset */
+            sourceIndex=-1;
+        }
+    }
+
+    if(cnv->preFromULength>=0) {
+        /* normal mode */
+        realSource=NULL;
+
+        /* avoid compiler warnings - not otherwise necessary, and the values do not matter */
+        realSourceLimit=NULL;
+        realFlush=FALSE;
+        realSourceIndex=0;
+    } else {
+        /*
+         * Previous m:n conversion stored source units from a partial match
+         * and failed to consume all of them.
+         * We need to "replay" them from a temporary buffer and convert them first.
+         */
+        realSource=pArgs->source;
+        realSourceLimit=pArgs->sourceLimit;
+        realFlush=pArgs->flush;
+        realSourceIndex=sourceIndex;
+
+        uprv_memcpy(replay, cnv->preFromU, -cnv->preFromULength*U_SIZEOF_UCHAR);
+        pArgs->source=replay;
+        pArgs->sourceLimit=replay-cnv->preFromULength;
+        pArgs->flush=FALSE;
+        sourceIndex=-1;
+
+        cnv->preFromULength=0;
+    }
+
+    /*
+     * loop for conversion and error handling
+     *
+     * loop {
+     *   convert
+     *   loop {
+     *     update offsets
+     *     handle end of input
+     *     handle errors/call callback
+     *   }
+     * }
+     */
+    for(;;) {
+        if(U_SUCCESS(*err)) {
+            /* convert */
+            fromUnicode(pArgs, err);
+
+            /*
+             * set a flag for whether the converter
+             * successfully processed the end of the input
+             *
+             * need not check cnv->preFromULength==0 because a replay (<0) will cause
+             * s<sourceLimit before converterSawEndOfInput is checked
+             */
+            converterSawEndOfInput=
+                (UBool)(U_SUCCESS(*err) &&
+                        pArgs->flush && pArgs->source==pArgs->sourceLimit &&
+                        cnv->fromUChar32==0);
+        } else {
+            /* handle error from ucnv_convertEx() */
+            converterSawEndOfInput=FALSE;
+        }
+
+        /* no callback called yet for this iteration */
+        calledCallback=FALSE;
+
+        /* no sourceIndex adjustment for conversion, only for callback output */
+        errorInputLength=0;
+
+        /*
+         * loop for offsets and error handling
+         *
+         * iterates at most 3 times:
+         * 1. to clean up after the conversion function
+         * 2. after the callback
+         * 3. after the callback again if there was truncated input
+         */
+        for(;;) {
+            /* update offsets if we write any */
+            if(offsets!=NULL) {
+                int32_t length=(int32_t)(pArgs->target-t);
+                if(length>0) {
+                    _updateOffsets(offsets, length, sourceIndex, errorInputLength);
+
+                    /*
+                     * if a converter handles offsets and updates the offsets
+                     * pointer at the end, then pArgs->offset should not change
+                     * here;
+                     * however, some converters do not handle offsets at all
+                     * (sourceIndex<0) or may not update the offsets pointer
+                     */
+                    pArgs->offsets=offsets+=length;
+                }
+
+                if(sourceIndex>=0) {
+                    sourceIndex+=(int32_t)(pArgs->source-s);
+                }
+            }
+
+            if(cnv->preFromULength<0) {
+                /*
+                 * switch the source to new replay units (cannot occur while replaying)
+                 * after offset handling and before end-of-input and callback handling
+                 */
+                if(realSource==NULL) {
+                    realSource=pArgs->source;
+                    realSourceLimit=pArgs->sourceLimit;
+                    realFlush=pArgs->flush;
+                    realSourceIndex=sourceIndex;
+
+                    uprv_memcpy(replay, cnv->preFromU, -cnv->preFromULength*U_SIZEOF_UCHAR);
+                    pArgs->source=replay;
+                    pArgs->sourceLimit=replay-cnv->preFromULength;
+                    pArgs->flush=FALSE;
+                    if((sourceIndex+=cnv->preFromULength)<0) {
+                        sourceIndex=-1;
+                    }
+
+                    cnv->preFromULength=0;
+                } else {
+                    /* see implementation note before _fromUnicodeWithCallback() */
+                    U_ASSERT(realSource==NULL);
+                    *err=U_INTERNAL_PROGRAM_ERROR;
+                }
+            }
+
+            /* update pointers */
+            s=pArgs->source;
+            t=pArgs->target;
+
+            if(U_SUCCESS(*err)) {
+                if(s<pArgs->sourceLimit) {
+                    /*
+                     * continue with the conversion loop while there is still input left
+                     * (continue converting by breaking out of only the inner loop)
+                     */
+                    break;
+                } else if(realSource!=NULL) {
+                    /* switch back from replaying to the real source and continue */
+                    pArgs->source=realSource;
+                    pArgs->sourceLimit=realSourceLimit;
+                    pArgs->flush=realFlush;
+                    sourceIndex=realSourceIndex;
+
+                    realSource=NULL;
+                    break;
+                } else if(pArgs->flush && cnv->fromUChar32!=0) {
+                    /*
+                     * the entire input stream is consumed
+                     * and there is a partial, truncated input sequence left
+                     */
+
+                    /* inject an error and continue with callback handling */
+                    *err=U_TRUNCATED_CHAR_FOUND;
+                    calledCallback=FALSE; /* new error condition */
+                } else {
+                    /* input consumed */
+                    if(pArgs->flush) {
+                        /*
+                         * return to the conversion loop once more if the flush
+                         * flag is set and the conversion function has not
+                         * successfully processed the end of the input yet
+                         *
+                         * (continue converting by breaking out of only the inner loop)
+                         */
+                        if(!converterSawEndOfInput) {
+                            break;
+                        }
+
+                        /* reset the converter without calling the callback function */
+                        _reset(cnv, UCNV_RESET_FROM_UNICODE, FALSE);
+                    }
+
+                    /* done successfully */
+                    return;
+                }
+            }
+
+            /* U_FAILURE(*err) */
+            {
+                UErrorCode e;
+
+                if( calledCallback ||
+                    (e=*err)==U_BUFFER_OVERFLOW_ERROR ||
+                    (e!=U_INVALID_CHAR_FOUND &&
+                     e!=U_ILLEGAL_CHAR_FOUND &&
+                     e!=U_TRUNCATED_CHAR_FOUND)
+                ) {
+                    /*
+                     * the callback did not or cannot resolve the error:
+                     * set output pointers and return
+                     *
+                     * the check for buffer overflow is redundant but it is
+                     * a high-runner case and hopefully documents the intent
+                     * well
+                     *
+                     * if we were replaying, then the replay buffer must be
+                     * copied back into the UConverter
+                     * and the real arguments must be restored
+                     */
+                    if(realSource!=NULL) {
+                        int32_t length;
+
+                        U_ASSERT(cnv->preFromULength==0);
+
+                        length=(int32_t)(pArgs->sourceLimit-pArgs->source);
+                        if(length>0) {
+                            uprv_memcpy(cnv->preFromU, pArgs->source, length*U_SIZEOF_UCHAR);
+                            cnv->preFromULength=(int8_t)-length;
+                        }
+
+                        pArgs->source=realSource;
+                        pArgs->sourceLimit=realSourceLimit;
+                        pArgs->flush=realFlush;
+                    }
+
+                    return;
+                }
+            }
+
+            /* callback handling */
+            {
+                UChar32 codePoint;
+
+                /* get and write the code point */
+                codePoint=cnv->fromUChar32;
+                errorInputLength=0;
+                U16_APPEND_UNSAFE(cnv->invalidUCharBuffer, errorInputLength, codePoint);
+                cnv->invalidUCharLength=(int8_t)errorInputLength;
+
+                /* set the converter state to deal with the next character */
+                cnv->fromUChar32=0;
+
+                /* call the callback function */
+                cnv->fromUCharErrorBehaviour(cnv->fromUContext, pArgs,
+                    cnv->invalidUCharBuffer, errorInputLength, codePoint,
+                    *err==U_INVALID_CHAR_FOUND ? UCNV_UNASSIGNED : UCNV_ILLEGAL,
+                    err);
+            }
+
+            /*
+             * loop back to the offset handling
+             *
+             * this flag will indicate after offset handling
+             * that a callback was called;
+             * if the callback did not resolve the error, then we return
+             */
+            calledCallback=TRUE;
+        }
+    }
+}
+
+/*
+ * Output the fromUnicode overflow buffer.
+ * Call this function if(cnv->charErrorBufferLength>0).
+ * @return TRUE if overflow
+ */
+static UBool
+ucnv_outputOverflowFromUnicode(UConverter *cnv,
+                               char **target, const char *targetLimit,
+                               int32_t **pOffsets,
+                               UErrorCode *err) {
+    int32_t *offsets;
+    char *overflow, *t;
+    int32_t i, length;
+
+    t=*target;
+    if(pOffsets!=NULL) {
+        offsets=*pOffsets;
+    } else {
+        offsets=NULL;
+    }
+
+    overflow=(char *)cnv->charErrorBuffer;
+    length=cnv->charErrorBufferLength;
+    i=0;
+    while(i<length) {
+        if(t==targetLimit) {
+            /* the overflow buffer contains too much, keep the rest */
+            int32_t j=0;
+
+            do {
+                overflow[j++]=overflow[i++];
+            } while(i<length);
+
+            cnv->charErrorBufferLength=(int8_t)j;
+            *target=t;
+            if(offsets!=NULL) {
+                *pOffsets=offsets;
+            }
+            *err=U_BUFFER_OVERFLOW_ERROR;
+            return TRUE;
+        }
+
+        /* copy the overflow contents to the target */
+        *t++=overflow[i++];
+        if(offsets!=NULL) {
+            *offsets++=-1; /* no source index available for old output */
+        }
+    }
+
+    /* the overflow buffer is completely copied to the target */
+    cnv->charErrorBufferLength=0;
+    *target=t;
+    if(offsets!=NULL) {
+        *pOffsets=offsets;
+    }
+    return FALSE;
+}
+
+U_CAPI void U_EXPORT2
+ucnv_fromUnicode(UConverter *cnv,
+                 char **target, const char *targetLimit,
+                 const UChar **source, const UChar *sourceLimit,
+                 int32_t *offsets,
+                 UBool flush,
+                 UErrorCode *err) {
+    UConverterFromUnicodeArgs args;
+    const UChar *s;
+    char *t;
+
+    /* check parameters */
+    if(err==NULL || U_FAILURE(*err)) {
+        return;
+    }
+
+    if(cnv==NULL || target==NULL || source==NULL) {
+        *err=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    s=*source;
+    t=*target;
+
+    if ((const void *)U_MAX_PTR(sourceLimit) == (const void *)sourceLimit) {
+        /*
+        Prevent code from going into an infinite loop in case we do hit this
+        limit. The limit pointer is expected to be on a UChar * boundary.
+        This also prevents the next argument check from failing.
+        */
+        sourceLimit = (const UChar *)(((const char *)sourceLimit) - 1);
+    }
+
+    /*
+     * All these conditions should never happen.
+     *
+     * 1) Make sure that the limits are >= to the address source or target
+     *
+     * 2) Make sure that the buffer sizes do not exceed the number range for
+     * int32_t because some functions use the size (in units or bytes)
+     * rather than comparing pointers, and because offsets are int32_t values.
+     *
+     * size_t is guaranteed to be unsigned and large enough for the job.
+     *
+     * Return with an error instead of adjusting the limits because we would
+     * not be able to maintain the semantics that either the source must be
+     * consumed or the target filled (unless an error occurs).
+     * An adjustment would be targetLimit=t+0x7fffffff; for example.
+     *
+     * 3) Make sure that the user didn't incorrectly cast a UChar * pointer
+     * to a char * pointer and provide an incomplete UChar code unit.
+     */
+    if (sourceLimit<s || targetLimit<t ||
+        ((size_t)(sourceLimit-s)>(size_t)0x3fffffff && sourceLimit>s) ||
+        ((size_t)(targetLimit-t)>(size_t)0x7fffffff && targetLimit>t) ||
+        (((const char *)sourceLimit-(const char *)s) & 1) != 0)
+    {
+        *err=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    
+    /* output the target overflow buffer */
+    if( cnv->charErrorBufferLength>0 &&
+        ucnv_outputOverflowFromUnicode(cnv, target, targetLimit, &offsets, err)
+    ) {
+        /* U_BUFFER_OVERFLOW_ERROR */
+        return;
+    }
+    /* *target may have moved, therefore stop using t */
+
+    if(!flush && s==sourceLimit && cnv->preFromULength>=0) {
+        /* the overflow buffer is emptied and there is no new input: we are done */
+        return;
+    }
+
+    /*
+     * Do not simply return with a buffer overflow error if
+     * !flush && t==targetLimit
+     * because it is possible that the source will not generate any output.
+     * For example, the skip callback may be called;
+     * it does not output anything.
+     */
+
+    /* prepare the converter arguments */
+    args.converter=cnv;
+    args.flush=flush;
+    args.offsets=offsets;
+    args.source=s;
+    args.sourceLimit=sourceLimit;
+    args.target=*target;
+    args.targetLimit=targetLimit;
+    args.size=sizeof(args);
+
+    _fromUnicodeWithCallback(&args, err);
+
+    *source=args.source;
+    *target=args.target;
+}
+
+/* ucnv_toUnicode() --------------------------------------------------------- */
+
+static void
+_toUnicodeWithCallback(UConverterToUnicodeArgs *pArgs, UErrorCode *err) {
+    UConverterToUnicode toUnicode;
+    UConverter *cnv;
+    const char *s;
+    UChar *t;
+    int32_t *offsets;
+    int32_t sourceIndex;
+    int32_t errorInputLength;
+    UBool converterSawEndOfInput, calledCallback;
+
+    /* variables for m:n conversion */
+    char replay[UCNV_EXT_MAX_BYTES];
+    const char *realSource, *realSourceLimit;
+    int32_t realSourceIndex;
+    UBool realFlush;
+
+    cnv=pArgs->converter;
+    s=pArgs->source;
+    t=pArgs->target;
+    offsets=pArgs->offsets;
+
+    /* get the converter implementation function */
+    sourceIndex=0;
+    if(offsets==NULL) {
+        toUnicode=cnv->sharedData->impl->toUnicode;
+    } else {
+        toUnicode=cnv->sharedData->impl->toUnicodeWithOffsets;
+        if(toUnicode==NULL) {
+            /* there is no WithOffsets implementation */
+            toUnicode=cnv->sharedData->impl->toUnicode;
+            /* we will write -1 for each offset */
+            sourceIndex=-1;
+        }
+    }
+
+    if(cnv->preToULength>=0) {
+        /* normal mode */
+        realSource=NULL;
+
+        /* avoid compiler warnings - not otherwise necessary, and the values do not matter */
+        realSourceLimit=NULL;
+        realFlush=FALSE;
+        realSourceIndex=0;
+    } else {
+        /*
+         * Previous m:n conversion stored source units from a partial match
+         * and failed to consume all of them.
+         * We need to "replay" them from a temporary buffer and convert them first.
+         */
+        realSource=pArgs->source;
+        realSourceLimit=pArgs->sourceLimit;
+        realFlush=pArgs->flush;
+        realSourceIndex=sourceIndex;
+
+        uprv_memcpy(replay, cnv->preToU, -cnv->preToULength);
+        pArgs->source=replay;
+        pArgs->sourceLimit=replay-cnv->preToULength;
+        pArgs->flush=FALSE;
+        sourceIndex=-1;
+
+        cnv->preToULength=0;
+    }
+
+    /*
+     * loop for conversion and error handling
+     *
+     * loop {
+     *   convert
+     *   loop {
+     *     update offsets
+     *     handle end of input
+     *     handle errors/call callback
+     *   }
+     * }
+     */
+    for(;;) {
+        if(U_SUCCESS(*err)) {
+            /* convert */
+            toUnicode(pArgs, err);
+
+            /*
+             * set a flag for whether the converter
+             * successfully processed the end of the input
+             *
+             * need not check cnv->preToULength==0 because a replay (<0) will cause
+             * s<sourceLimit before converterSawEndOfInput is checked
+             */
+            converterSawEndOfInput=
+                (UBool)(U_SUCCESS(*err) &&
+                        pArgs->flush && pArgs->source==pArgs->sourceLimit &&
+                        cnv->toULength==0);
+        } else {
+            /* handle error from getNextUChar() or ucnv_convertEx() */
+            converterSawEndOfInput=FALSE;
+        }
+
+        /* no callback called yet for this iteration */
+        calledCallback=FALSE;
+
+        /* no sourceIndex adjustment for conversion, only for callback output */
+        errorInputLength=0;
+
+        /*
+         * loop for offsets and error handling
+         *
+         * iterates at most 3 times:
+         * 1. to clean up after the conversion function
+         * 2. after the callback
+         * 3. after the callback again if there was truncated input
+         */
+        for(;;) {
+            /* update offsets if we write any */
+            if(offsets!=NULL) {
+                int32_t length=(int32_t)(pArgs->target-t);
+                if(length>0) {
+                    _updateOffsets(offsets, length, sourceIndex, errorInputLength);
+
+                    /*
+                     * if a converter handles offsets and updates the offsets
+                     * pointer at the end, then pArgs->offset should not change
+                     * here;
+                     * however, some converters do not handle offsets at all
+                     * (sourceIndex<0) or may not update the offsets pointer
+                     */
+                    pArgs->offsets=offsets+=length;
+                }
+
+                if(sourceIndex>=0) {
+                    sourceIndex+=(int32_t)(pArgs->source-s);
+                }
+            }
+
+            if(cnv->preToULength<0) {
+                /*
+                 * switch the source to new replay units (cannot occur while replaying)
+                 * after offset handling and before end-of-input and callback handling
+                 */
+                if(realSource==NULL) {
+                    realSource=pArgs->source;
+                    realSourceLimit=pArgs->sourceLimit;
+                    realFlush=pArgs->flush;
+                    realSourceIndex=sourceIndex;
+
+                    uprv_memcpy(replay, cnv->preToU, -cnv->preToULength);
+                    pArgs->source=replay;
+                    pArgs->sourceLimit=replay-cnv->preToULength;
+                    pArgs->flush=FALSE;
+                    if((sourceIndex+=cnv->preToULength)<0) {
+                        sourceIndex=-1;
+                    }
+
+                    cnv->preToULength=0;
+                } else {
+                    /* see implementation note before _fromUnicodeWithCallback() */
+                    U_ASSERT(realSource==NULL);
+                    *err=U_INTERNAL_PROGRAM_ERROR;
+                }
+            }
+
+            /* update pointers */
+            s=pArgs->source;
+            t=pArgs->target;
+
+            if(U_SUCCESS(*err)) {
+                if(s<pArgs->sourceLimit) {
+                    /*
+                     * continue with the conversion loop while there is still input left
+                     * (continue converting by breaking out of only the inner loop)
+                     */
+                    break;
+                } else if(realSource!=NULL) {
+                    /* switch back from replaying to the real source and continue */
+                    pArgs->source=realSource;
+                    pArgs->sourceLimit=realSourceLimit;
+                    pArgs->flush=realFlush;
+                    sourceIndex=realSourceIndex;
+
+                    realSource=NULL;
+                    break;
+                } else if(pArgs->flush && cnv->toULength>0) {
+                    /*
+                     * the entire input stream is consumed
+                     * and there is a partial, truncated input sequence left
+                     */
+
+                    /* inject an error and continue with callback handling */
+                    *err=U_TRUNCATED_CHAR_FOUND;
+                    calledCallback=FALSE; /* new error condition */
+                } else {
+                    /* input consumed */
+                    if(pArgs->flush) {
+                        /*
+                         * return to the conversion loop once more if the flush
+                         * flag is set and the conversion function has not
+                         * successfully processed the end of the input yet
+                         *
+                         * (continue converting by breaking out of only the inner loop)
+                         */
+                        if(!converterSawEndOfInput) {
+                            break;
+                        }
+
+                        /* reset the converter without calling the callback function */
+                        _reset(cnv, UCNV_RESET_TO_UNICODE, FALSE);
+                    }
+
+                    /* done successfully */
+                    return;
+                }
+            }
+
+            /* U_FAILURE(*err) */
+            {
+                UErrorCode e;
+
+                if( calledCallback ||
+                    (e=*err)==U_BUFFER_OVERFLOW_ERROR ||
+                    (e!=U_INVALID_CHAR_FOUND &&
+                     e!=U_ILLEGAL_CHAR_FOUND &&
+                     e!=U_TRUNCATED_CHAR_FOUND &&
+                     e!=U_ILLEGAL_ESCAPE_SEQUENCE &&
+                     e!=U_UNSUPPORTED_ESCAPE_SEQUENCE)
+                ) {
+                    /*
+                     * the callback did not or cannot resolve the error:
+                     * set output pointers and return
+                     *
+                     * the check for buffer overflow is redundant but it is
+                     * a high-runner case and hopefully documents the intent
+                     * well
+                     *
+                     * if we were replaying, then the replay buffer must be
+                     * copied back into the UConverter
+                     * and the real arguments must be restored
+                     */
+                    if(realSource!=NULL) {
+                        int32_t length;
+
+                        U_ASSERT(cnv->preToULength==0);
+
+                        length=(int32_t)(pArgs->sourceLimit-pArgs->source);
+                        if(length>0) {
+                            uprv_memcpy(cnv->preToU, pArgs->source, length);
+                            cnv->preToULength=(int8_t)-length;
+                        }
+
+                        pArgs->source=realSource;
+                        pArgs->sourceLimit=realSourceLimit;
+                        pArgs->flush=realFlush;
+                    }
+
+                    return;
+                }
+            }
+
+            /* copy toUBytes[] to invalidCharBuffer[] */
+            errorInputLength=cnv->invalidCharLength=cnv->toULength;
+            if(errorInputLength>0) {
+                uprv_memcpy(cnv->invalidCharBuffer, cnv->toUBytes, errorInputLength);
+            }
+
+            /* set the converter state to deal with the next character */
+            cnv->toULength=0;
+
+            /* call the callback function */
+            if(cnv->toUCallbackReason==UCNV_ILLEGAL && *err==U_INVALID_CHAR_FOUND) {
+                cnv->toUCallbackReason = UCNV_UNASSIGNED;
+            }
+            cnv->fromCharErrorBehaviour(cnv->toUContext, pArgs,
+                cnv->invalidCharBuffer, errorInputLength,
+                cnv->toUCallbackReason,
+                err);
+            cnv->toUCallbackReason = UCNV_ILLEGAL; /* reset to default value */
+
+            /*
+             * loop back to the offset handling
+             *
+             * this flag will indicate after offset handling
+             * that a callback was called;
+             * if the callback did not resolve the error, then we return
+             */
+            calledCallback=TRUE;
+        }
+    }
+}
+
+/*
+ * Output the toUnicode overflow buffer.
+ * Call this function if(cnv->UCharErrorBufferLength>0).
+ * @return TRUE if overflow
+ */
+static UBool
+ucnv_outputOverflowToUnicode(UConverter *cnv,
+                             UChar **target, const UChar *targetLimit,
+                             int32_t **pOffsets,
+                             UErrorCode *err) {
+    int32_t *offsets;
+    UChar *overflow, *t;
+    int32_t i, length;
+
+    t=*target;
+    if(pOffsets!=NULL) {
+        offsets=*pOffsets;
+    } else {
+        offsets=NULL;
+    }
+
+    overflow=cnv->UCharErrorBuffer;
+    length=cnv->UCharErrorBufferLength;
+    i=0;
+    while(i<length) {
+        if(t==targetLimit) {
+            /* the overflow buffer contains too much, keep the rest */
+            int32_t j=0;
+
+            do {
+                overflow[j++]=overflow[i++];
+            } while(i<length);
+
+            cnv->UCharErrorBufferLength=(int8_t)j;
+            *target=t;
+            if(offsets!=NULL) {
+                *pOffsets=offsets;
+            }
+            *err=U_BUFFER_OVERFLOW_ERROR;
+            return TRUE;
+        }
+
+        /* copy the overflow contents to the target */
+        *t++=overflow[i++];
+        if(offsets!=NULL) {
+            *offsets++=-1; /* no source index available for old output */
+        }
+    }
+
+    /* the overflow buffer is completely copied to the target */
+    cnv->UCharErrorBufferLength=0;
+    *target=t;
+    if(offsets!=NULL) {
+        *pOffsets=offsets;
+    }
+    return FALSE;
+}
+
+U_CAPI void U_EXPORT2
+ucnv_toUnicode(UConverter *cnv,
+               UChar **target, const UChar *targetLimit,
+               const char **source, const char *sourceLimit,
+               int32_t *offsets,
+               UBool flush,
+               UErrorCode *err) {
+    UConverterToUnicodeArgs args;
+    const char *s;
+    UChar *t;
+
+    /* check parameters */
+    if(err==NULL || U_FAILURE(*err)) {
+        return;
+    }
+
+    if(cnv==NULL || target==NULL || source==NULL) {
+        *err=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    s=*source;
+    t=*target;
+
+    if ((const void *)U_MAX_PTR(targetLimit) == (const void *)targetLimit) {
+        /*
+        Prevent code from going into an infinite loop in case we do hit this
+        limit. The limit pointer is expected to be on a UChar * boundary.
+        This also prevents the next argument check from failing.
+        */
+        targetLimit = (const UChar *)(((const char *)targetLimit) - 1);
+    }
+
+    /*
+     * All these conditions should never happen.
+     *
+     * 1) Make sure that the limits are >= to the address source or target
+     *
+     * 2) Make sure that the buffer sizes do not exceed the number range for
+     * int32_t because some functions use the size (in units or bytes)
+     * rather than comparing pointers, and because offsets are int32_t values.
+     *
+     * size_t is guaranteed to be unsigned and large enough for the job.
+     *
+     * Return with an error instead of adjusting the limits because we would
+     * not be able to maintain the semantics that either the source must be
+     * consumed or the target filled (unless an error occurs).
+     * An adjustment would be sourceLimit=t+0x7fffffff; for example.
+     *
+     * 3) Make sure that the user didn't incorrectly cast a UChar * pointer
+     * to a char * pointer and provide an incomplete UChar code unit.
+     */
+    if (sourceLimit<s || targetLimit<t ||
+        ((size_t)(sourceLimit-s)>(size_t)0x7fffffff && sourceLimit>s) ||
+        ((size_t)(targetLimit-t)>(size_t)0x3fffffff && targetLimit>t) ||
+        (((const char *)targetLimit-(const char *)t) & 1) != 0
+    ) {
+        *err=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    
+    /* output the target overflow buffer */
+    if( cnv->UCharErrorBufferLength>0 &&
+        ucnv_outputOverflowToUnicode(cnv, target, targetLimit, &offsets, err)
+    ) {
+        /* U_BUFFER_OVERFLOW_ERROR */
+        return;
+    }
+    /* *target may have moved, therefore stop using t */
+
+    if(!flush && s==sourceLimit && cnv->preToULength>=0) {
+        /* the overflow buffer is emptied and there is no new input: we are done */
+        return;
+    }
+
+    /*
+     * Do not simply return with a buffer overflow error if
+     * !flush && t==targetLimit
+     * because it is possible that the source will not generate any output.
+     * For example, the skip callback may be called;
+     * it does not output anything.
+     */
+
+    /* prepare the converter arguments */
+    args.converter=cnv;
+    args.flush=flush;
+    args.offsets=offsets;
+    args.source=s;
+    args.sourceLimit=sourceLimit;
+    args.target=*target;
+    args.targetLimit=targetLimit;
+    args.size=sizeof(args);
+
+    _toUnicodeWithCallback(&args, err);
+
+    *source=args.source;
+    *target=args.target;
+}
+
+/* ucnv_to/fromUChars() ----------------------------------------------------- */
+
+U_CAPI int32_t U_EXPORT2
+ucnv_fromUChars(UConverter *cnv,
+                char *dest, int32_t destCapacity,
+                const UChar *src, int32_t srcLength,
+                UErrorCode *pErrorCode) {
+    const UChar *srcLimit;
+    char *originalDest, *destLimit;
+    int32_t destLength;
+
+    /* check arguments */
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    if( cnv==NULL ||
+        destCapacity<0 || (destCapacity>0 && dest==NULL) ||
+        srcLength<-1 || (srcLength!=0 && src==NULL)
+    ) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    /* initialize */
+    ucnv_resetFromUnicode(cnv);
+    originalDest=dest;
+    if(srcLength==-1) {
+        srcLength=u_strlen(src);
+    }
+    if(srcLength>0) {
+        srcLimit=src+srcLength;
+        destLimit=dest+destCapacity;
+
+        /* pin the destination limit to U_MAX_PTR; NULL check is for OS/400 */
+        if(destLimit<dest || (destLimit==NULL && dest!=NULL)) {
+            destLimit=(char *)U_MAX_PTR(dest);
+        }
+
+        /* perform the conversion */
+        ucnv_fromUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, pErrorCode);
+        destLength=(int32_t)(dest-originalDest);
+
+        /* if an overflow occurs, then get the preflighting length */
+        if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
+            char buffer[1024];
+
+            destLimit=buffer+sizeof(buffer);
+            do {
+                dest=buffer;
+                *pErrorCode=U_ZERO_ERROR;
+                ucnv_fromUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, pErrorCode);
+                destLength+=(int32_t)(dest-buffer);
+            } while(*pErrorCode==U_BUFFER_OVERFLOW_ERROR);
+        }
+    } else {
+        destLength=0;
+    }
+
+    return u_terminateChars(originalDest, destCapacity, destLength, pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+ucnv_toUChars(UConverter *cnv,
+              UChar *dest, int32_t destCapacity,
+              const char *src, int32_t srcLength,
+              UErrorCode *pErrorCode) {
+    const char *srcLimit;
+    UChar *originalDest, *destLimit;
+    int32_t destLength;
+
+    /* check arguments */
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    if( cnv==NULL ||
+        destCapacity<0 || (destCapacity>0 && dest==NULL) ||
+        srcLength<-1 || (srcLength!=0 && src==NULL))
+    {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    /* initialize */
+    ucnv_resetToUnicode(cnv);
+    originalDest=dest;
+    if(srcLength==-1) {
+        srcLength=(int32_t)uprv_strlen(src);
+    }
+    if(srcLength>0) {
+        srcLimit=src+srcLength;
+        destLimit=dest+destCapacity;
+
+        /* pin the destination limit to U_MAX_PTR; NULL check is for OS/400 */
+        if(destLimit<dest || (destLimit==NULL && dest!=NULL)) {
+            destLimit=(UChar *)U_MAX_PTR(dest);
+        }
+
+        /* perform the conversion */
+        ucnv_toUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, pErrorCode);
+        destLength=(int32_t)(dest-originalDest);
+
+        /* if an overflow occurs, then get the preflighting length */
+        if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR)
+        {
+            UChar buffer[1024];
+
+            destLimit=buffer+sizeof(buffer)/U_SIZEOF_UCHAR;
+            do {
+                dest=buffer;
+                *pErrorCode=U_ZERO_ERROR;
+                ucnv_toUnicode(cnv, &dest, destLimit, &src, srcLimit, 0, TRUE, pErrorCode);
+                destLength+=(int32_t)(dest-buffer);
+            }
+            while(*pErrorCode==U_BUFFER_OVERFLOW_ERROR);
+        }
+    } else {
+        destLength=0;
+    }
+
+    return u_terminateUChars(originalDest, destCapacity, destLength, pErrorCode);
+}
+
+/* ucnv_getNextUChar() ------------------------------------------------------ */
+
+U_CAPI UChar32 U_EXPORT2
+ucnv_getNextUChar(UConverter *cnv,
+                  const char **source, const char *sourceLimit,
+                  UErrorCode *err) {
+    UConverterToUnicodeArgs args;
+    UChar buffer[U16_MAX_LENGTH];
+    const char *s;
+    UChar32 c;
+    int32_t i, length;
+
+    /* check parameters */
+    if(err==NULL || U_FAILURE(*err)) {
+        return 0xffff;
+    }
+
+    if(cnv==NULL || source==NULL) {
+        *err=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0xffff;
+    }
+
+    s=*source;
+    if(sourceLimit<s) {
+        *err=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0xffff;
+    }
+
+    /*
+     * Make sure that the buffer sizes do not exceed the number range for
+     * int32_t because some functions use the size (in units or bytes)
+     * rather than comparing pointers, and because offsets are int32_t values.
+     *
+     * size_t is guaranteed to be unsigned and large enough for the job.
+     *
+     * Return with an error instead of adjusting the limits because we would
+     * not be able to maintain the semantics that either the source must be
+     * consumed or the target filled (unless an error occurs).
+     * An adjustment would be sourceLimit=t+0x7fffffff; for example.
+     */
+    if(((size_t)(sourceLimit-s)>(size_t)0x7fffffff && sourceLimit>s)) {
+        *err=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0xffff;
+    }
+
+    c=U_SENTINEL;
+
+    /* flush the target overflow buffer */
+    if(cnv->UCharErrorBufferLength>0) {
+        UChar *overflow;
+
+        overflow=cnv->UCharErrorBuffer;
+        i=0;
+        length=cnv->UCharErrorBufferLength;
+        U16_NEXT(overflow, i, length, c);
+
+        /* move the remaining overflow contents up to the beginning */
+        if((cnv->UCharErrorBufferLength=(int8_t)(length-i))>0) {
+            uprv_memmove(cnv->UCharErrorBuffer, cnv->UCharErrorBuffer+i,
+                         cnv->UCharErrorBufferLength*U_SIZEOF_UCHAR);
+        }
+
+        if(!U16_IS_LEAD(c) || i<length) {
+            return c;
+        }
+        /*
+         * Continue if the overflow buffer contained only a lead surrogate,
+         * in case the converter outputs single surrogates from complete
+         * input sequences.
+         */
+    }
+
+    /*
+     * flush==TRUE is implied for ucnv_getNextUChar()
+     *
+     * do not simply return even if s==sourceLimit because the converter may
+     * not have seen flush==TRUE before
+     */
+
+    /* prepare the converter arguments */
+    args.converter=cnv;
+    args.flush=TRUE;
+    args.offsets=NULL;
+    args.source=s;
+    args.sourceLimit=sourceLimit;
+    args.target=buffer;
+    args.targetLimit=buffer+1;
+    args.size=sizeof(args);
+
+    if(c<0) {
+        /*
+         * call the native getNextUChar() implementation if we are
+         * at a character boundary (toULength==0)
+         *
+         * unlike with _toUnicode(), getNextUChar() implementations must set
+         * U_TRUNCATED_CHAR_FOUND for truncated input,
+         * in addition to setting toULength/toUBytes[]
+         */
+        if(cnv->toULength==0 && cnv->sharedData->impl->getNextUChar!=NULL) {
+            c=cnv->sharedData->impl->getNextUChar(&args, err);
+            *source=s=args.source;
+            if(*err==U_INDEX_OUTOFBOUNDS_ERROR) {
+                /* reset the converter without calling the callback function */
+                _reset(cnv, UCNV_RESET_TO_UNICODE, FALSE);
+                return 0xffff; /* no output */
+            } else if(U_SUCCESS(*err) && c>=0) {
+                return c;
+            /*
+             * else fall through to use _toUnicode() because
+             *   UCNV_GET_NEXT_UCHAR_USE_TO_U: the native function did not want to handle it after all
+             *   U_FAILURE: call _toUnicode() for callback handling (do not output c)
+             */
+            }
+        }
+
+        /* convert to one UChar in buffer[0], or handle getNextUChar() errors */
+        _toUnicodeWithCallback(&args, err);
+
+        if(*err==U_BUFFER_OVERFLOW_ERROR) {
+            *err=U_ZERO_ERROR;
+        }
+
+        i=0;
+        length=(int32_t)(args.target-buffer);
+    } else {
+        /* write the lead surrogate from the overflow buffer */
+        buffer[0]=(UChar)c;
+        args.target=buffer+1;
+        i=0;
+        length=1;
+    }
+
+    /* buffer contents starts at i and ends before length */
+
+    if(U_FAILURE(*err)) {
+        c=0xffff; /* no output */
+    } else if(length==0) {
+        /* no input or only state changes */
+        *err=U_INDEX_OUTOFBOUNDS_ERROR;
+        /* no need to reset explicitly because _toUnicodeWithCallback() did it */
+        c=0xffff; /* no output */
+    } else {
+        c=buffer[0];
+        i=1;
+        if(!U16_IS_LEAD(c)) {
+            /* consume c=buffer[0], done */
+        } else {
+            /* got a lead surrogate, see if a trail surrogate follows */
+            UChar c2;
+
+            if(cnv->UCharErrorBufferLength>0) {
+                /* got overflow output from the conversion */
+                if(U16_IS_TRAIL(c2=cnv->UCharErrorBuffer[0])) {
+                    /* got a trail surrogate, too */
+                    c=U16_GET_SUPPLEMENTARY(c, c2);
+
+                    /* move the remaining overflow contents up to the beginning */
+                    if((--cnv->UCharErrorBufferLength)>0) {
+                        uprv_memmove(cnv->UCharErrorBuffer, cnv->UCharErrorBuffer+1,
+                                     cnv->UCharErrorBufferLength*U_SIZEOF_UCHAR);
+                    }
+                } else {
+                    /* c is an unpaired lead surrogate, just return it */
+                }
+            } else if(args.source<sourceLimit) {
+                /* convert once more, to buffer[1] */
+                args.targetLimit=buffer+2;
+                _toUnicodeWithCallback(&args, err);
+                if(*err==U_BUFFER_OVERFLOW_ERROR) {
+                    *err=U_ZERO_ERROR;
+                }
+
+                length=(int32_t)(args.target-buffer);
+                if(U_SUCCESS(*err) && length==2 && U16_IS_TRAIL(c2=buffer[1])) {
+                    /* got a trail surrogate, too */
+                    c=U16_GET_SUPPLEMENTARY(c, c2);
+                    i=2;
+                }
+            }
+        }
+    }
+
+    /*
+     * move leftover output from buffer[i..length[
+     * into the beginning of the overflow buffer
+     */
+    if(i<length) {
+        /* move further overflow back */
+        int32_t delta=length-i;
+        if((length=cnv->UCharErrorBufferLength)>0) {
+            uprv_memmove(cnv->UCharErrorBuffer+delta, cnv->UCharErrorBuffer,
+                         length*U_SIZEOF_UCHAR);
+        }
+        cnv->UCharErrorBufferLength=(int8_t)(length+delta);
+
+        cnv->UCharErrorBuffer[0]=buffer[i++];
+        if(delta>1) {
+            cnv->UCharErrorBuffer[1]=buffer[i];
+        }
+    }
+
+    *source=args.source;
+    return c;
+}
+
+/* ucnv_convert() and siblings ---------------------------------------------- */
+
+U_CAPI void U_EXPORT2
+ucnv_convertEx(UConverter *targetCnv, UConverter *sourceCnv,
+               char **target, const char *targetLimit,
+               const char **source, const char *sourceLimit,
+               UChar *pivotStart, UChar **pivotSource,
+               UChar **pivotTarget, const UChar *pivotLimit,
+               UBool reset, UBool flush,
+               UErrorCode *pErrorCode) {
+    UChar pivotBuffer[CHUNK_SIZE];
+    const UChar *myPivotSource;
+    UChar *myPivotTarget;
+    const char *s;
+    char *t;
+
+    UConverterToUnicodeArgs toUArgs;
+    UConverterFromUnicodeArgs fromUArgs;
+    UConverterConvert convert;
+
+    /* error checking */
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return;
+    }
+
+    if( targetCnv==NULL || sourceCnv==NULL ||
+        source==NULL || *source==NULL ||
+        target==NULL || *target==NULL || targetLimit==NULL
+    ) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    s=*source;
+    t=*target;
+    if((sourceLimit!=NULL && sourceLimit<s) || targetLimit<t) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    /*
+     * Make sure that the buffer sizes do not exceed the number range for
+     * int32_t. See ucnv_toUnicode() for a more detailed comment.
+     */
+    if(
+        (sourceLimit!=NULL && ((size_t)(sourceLimit-s)>(size_t)0x7fffffff && sourceLimit>s)) ||
+        ((size_t)(targetLimit-t)>(size_t)0x7fffffff && targetLimit>t)
+    ) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    
+    if(pivotStart==NULL) {
+        if(!flush) {
+            /* streaming conversion requires an explicit pivot buffer */
+            *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+            return;
+        }
+
+        /* use the stack pivot buffer */
+        myPivotSource=myPivotTarget=pivotStart=pivotBuffer;
+        pivotSource=(UChar **)&myPivotSource;
+        pivotTarget=&myPivotTarget;
+        pivotLimit=pivotBuffer+CHUNK_SIZE;
+    } else if(  pivotStart>=pivotLimit ||
+                pivotSource==NULL || *pivotSource==NULL ||
+                pivotTarget==NULL || *pivotTarget==NULL ||
+                pivotLimit==NULL
+    ) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    if(sourceLimit==NULL) {
+        /* get limit of single-byte-NUL-terminated source string */
+        sourceLimit=uprv_strchr(*source, 0);
+    }
+
+    if(reset) {
+        ucnv_resetToUnicode(sourceCnv);
+        ucnv_resetFromUnicode(targetCnv);
+        *pivotSource=*pivotTarget=pivotStart;
+    } else if(targetCnv->charErrorBufferLength>0) {
+        /* output the targetCnv overflow buffer */
+        if(ucnv_outputOverflowFromUnicode(targetCnv, target, targetLimit, NULL, pErrorCode)) {
+            /* U_BUFFER_OVERFLOW_ERROR */
+            return;
+        }
+        /* *target has moved, therefore stop using t */
+
+        if( !flush &&
+            targetCnv->preFromULength>=0 && *pivotSource==*pivotTarget &&
+            sourceCnv->UCharErrorBufferLength==0 && sourceCnv->preToULength>=0 && s==sourceLimit
+        ) {
+            /* the fromUnicode overflow buffer is emptied and there is no new input: we are done */
+            return;
+        }
+    }
+
+    /* Is direct-UTF-8 conversion available? */
+    if( sourceCnv->sharedData->staticData->conversionType==UCNV_UTF8 &&
+        targetCnv->sharedData->impl->fromUTF8!=NULL
+    ) {
+        convert=targetCnv->sharedData->impl->fromUTF8;
+    } else if( targetCnv->sharedData->staticData->conversionType==UCNV_UTF8 &&
+               sourceCnv->sharedData->impl->toUTF8!=NULL
+    ) {
+        convert=sourceCnv->sharedData->impl->toUTF8;
+    } else {
+        convert=NULL;
+    }
+
+    /*
+     * If direct-UTF-8 conversion is available, then we use a smaller
+     * pivot buffer for error handling and partial matches
+     * so that we quickly return to direct conversion.
+     *
+     * 32 is large enough for UCNV_EXT_MAX_UCHARS and UCNV_ERROR_BUFFER_LENGTH.
+     *
+     * We could reduce the pivot buffer size further, at the cost of
+     * buffer overflows from callbacks.
+     * The pivot buffer should not be smaller than the maximum number of
+     * fromUnicode extension table input UChars
+     * (for m:n conversion, see
+     * targetCnv->sharedData->mbcs.extIndexes[UCNV_EXT_COUNT_UCHARS])
+     * or 2 for surrogate pairs.
+     *
+     * Too small a buffer can cause thrashing between pivoting and direct
+     * conversion, with function call overhead outweighing the benefits
+     * of direct conversion.
+     */
+    if(convert!=NULL && (pivotLimit-pivotStart)>32) {
+        pivotLimit=pivotStart+32;
+    }
+
+    /* prepare the converter arguments */
+    fromUArgs.converter=targetCnv;
+    fromUArgs.flush=FALSE;
+    fromUArgs.offsets=NULL;
+    fromUArgs.target=*target;
+    fromUArgs.targetLimit=targetLimit;
+    fromUArgs.size=sizeof(fromUArgs);
+
+    toUArgs.converter=sourceCnv;
+    toUArgs.flush=flush;
+    toUArgs.offsets=NULL;
+    toUArgs.source=s;
+    toUArgs.sourceLimit=sourceLimit;
+    toUArgs.targetLimit=pivotLimit;
+    toUArgs.size=sizeof(toUArgs);
+
+    /*
+     * TODO: Consider separating this function into two functions,
+     * extracting exactly the conversion loop,
+     * for readability and to reduce the set of visible variables.
+     *
+     * Otherwise stop using s and t from here on.
+     */
+    s=t=NULL;
+
+    /*
+     * conversion loop
+     *
+     * The sequence of steps in the loop may appear backward,
+     * but the principle is simple:
+     * In the chain of
+     *   source - sourceCnv overflow - pivot - targetCnv overflow - target
+     * empty out later buffers before refilling them from earlier ones.
+     *
+     * The targetCnv overflow buffer is flushed out only once before the loop.
+     */
+    for(;;) {
+        /*
+         * if(pivot not empty or error or replay or flush fromUnicode) {
+         *   fromUnicode(pivot -> target);
+         * }
+         *
+         * For pivoting conversion; and for direct conversion for
+         * error callback handling and flushing the replay buffer.
+         */
+        if( *pivotSource<*pivotTarget ||
+            U_FAILURE(*pErrorCode) ||
+            targetCnv->preFromULength<0 ||
+            fromUArgs.flush
+        ) {
+            fromUArgs.source=*pivotSource;
+            fromUArgs.sourceLimit=*pivotTarget;
+            _fromUnicodeWithCallback(&fromUArgs, pErrorCode);
+            if(U_FAILURE(*pErrorCode)) {
+                /* target overflow, or conversion error */
+                *pivotSource=(UChar *)fromUArgs.source;
+                break;
+            }
+
+            /*
+             * _fromUnicodeWithCallback() must have consumed the pivot contents
+             * (*pivotSource==*pivotTarget) since it returned with U_SUCCESS()
+             */
+        }
+
+        /* The pivot buffer is empty; reset it so we start at pivotStart. */
+        *pivotSource=*pivotTarget=pivotStart;
+
+        /*
+         * if(sourceCnv overflow buffer not empty) {
+         *     move(sourceCnv overflow buffer -> pivot);
+         *     continue;
+         * }
+         */
+        /* output the sourceCnv overflow buffer */
+        if(sourceCnv->UCharErrorBufferLength>0) {
+            if(ucnv_outputOverflowToUnicode(sourceCnv, pivotTarget, pivotLimit, NULL, pErrorCode)) {
+                /* U_BUFFER_OVERFLOW_ERROR */
+                *pErrorCode=U_ZERO_ERROR;
+            }
+            continue;
+        }
+
+        /*
+         * check for end of input and break if done
+         *
+         * Checking both flush and fromUArgs.flush ensures that the converters
+         * have been called with the flush flag set if the ucnv_convertEx()
+         * caller set it.
+         */
+        if( toUArgs.source==sourceLimit &&
+            sourceCnv->preToULength>=0 && sourceCnv->toULength==0 &&
+            (!flush || fromUArgs.flush)
+        ) {
+            /* done successfully */
+            break;
+        }
+
+        /*
+         * use direct conversion if available
+         * but not if continuing a partial match
+         * or flushing the toUnicode replay buffer
+         */
+        if(convert!=NULL && targetCnv->preFromUFirstCP<0 && sourceCnv->preToULength==0) {
+            if(*pErrorCode==U_USING_DEFAULT_WARNING) {
+                /* remove a warning that may be set by this function */
+                *pErrorCode=U_ZERO_ERROR;
+            }
+            convert(&fromUArgs, &toUArgs, pErrorCode);
+            if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
+                break;
+            } else if(U_FAILURE(*pErrorCode)) {
+                if(sourceCnv->toULength>0) {
+                    /*
+                     * Fall through to calling _toUnicodeWithCallback()
+                     * for callback handling.
+                     *
+                     * The pivot buffer will be reset with
+                     *   *pivotSource=*pivotTarget=pivotStart;
+                     * which indicates a toUnicode error to the caller
+                     * (*pivotSource==pivotStart shows no pivot UChars consumed).
+                     */
+                } else {
+                    /*
+                     * Indicate a fromUnicode error to the caller
+                     * (*pivotSource>pivotStart shows some pivot UChars consumed).
+                     */
+                    *pivotSource=*pivotTarget=pivotStart+1;
+                    /*
+                     * Loop around to calling _fromUnicodeWithCallbacks()
+                     * for callback handling.
+                     */
+                    continue;
+                }
+            } else if(*pErrorCode==U_USING_DEFAULT_WARNING) {
+                /*
+                 * No error, but the implementation requested to temporarily
+                 * fall back to pivoting.
+                 */
+                *pErrorCode=U_ZERO_ERROR;
+            /*
+             * The following else branches are almost identical to the end-of-input
+             * handling in _toUnicodeWithCallback().
+             * Avoid calling it just for the end of input.
+             */
+            } else if(flush && sourceCnv->toULength>0) { /* flush==toUArgs.flush */
+                /*
+                 * the entire input stream is consumed
+                 * and there is a partial, truncated input sequence left
+                 */
+
+                /* inject an error and continue with callback handling */
+                *pErrorCode=U_TRUNCATED_CHAR_FOUND;
+            } else {
+                /* input consumed */
+                if(flush) {
+                    /* reset the converters without calling the callback functions */
+                    _reset(sourceCnv, UCNV_RESET_TO_UNICODE, FALSE);
+                    _reset(targetCnv, UCNV_RESET_FROM_UNICODE, FALSE);
+                }
+
+                /* done successfully */
+                break;
+            }
+        }
+        
+        /*
+         * toUnicode(source -> pivot);
+         *
+         * For pivoting conversion; and for direct conversion for
+         * error callback handling, continuing partial matches
+         * and flushing the replay buffer.
+         *
+         * The pivot buffer is empty and reset.
+         */
+        toUArgs.target=pivotStart; /* ==*pivotTarget */
+        /* toUArgs.targetLimit=pivotLimit; already set before the loop */
+        _toUnicodeWithCallback(&toUArgs, pErrorCode);
+        *pivotTarget=toUArgs.target;
+        if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
+            /* pivot overflow: continue with the conversion loop */
+            *pErrorCode=U_ZERO_ERROR;
+        } else if(U_FAILURE(*pErrorCode) || (!flush && *pivotTarget==pivotStart)) {
+            /* conversion error, or there was nothing left to convert */
+            break;
+        }
+        /*
+         * else:
+         * _toUnicodeWithCallback() wrote into the pivot buffer,
+         * continue with fromUnicode conversion.
+         *
+         * Set the fromUnicode flush flag if we flush and if toUnicode has
+         * processed the end of the input.
+         */
+        if( flush && toUArgs.source==sourceLimit &&
+            sourceCnv->preToULength>=0 &&
+            sourceCnv->UCharErrorBufferLength==0
+        ) {
+            fromUArgs.flush=TRUE;
+        }
+    }
+
+    /*
+     * The conversion loop is exited when one of the following is true:
+     * - the entire source text has been converted successfully to the target buffer
+     * - a target buffer overflow occurred
+     * - a conversion error occurred
+     */
+
+    *source=toUArgs.source;
+    *target=fromUArgs.target;
+
+    /* terminate the target buffer if possible */
+    if(flush && U_SUCCESS(*pErrorCode)) {
+        if(*target!=targetLimit) {
+            **target=0;
+            if(*pErrorCode==U_STRING_NOT_TERMINATED_WARNING) {
+                *pErrorCode=U_ZERO_ERROR;
+            }
+        } else {
+            *pErrorCode=U_STRING_NOT_TERMINATED_WARNING;
+        }
+    }
+}
+
+/* internal implementation of ucnv_convert() etc. with preflighting */
+static int32_t
+ucnv_internalConvert(UConverter *outConverter, UConverter *inConverter,
+                     char *target, int32_t targetCapacity,
+                     const char *source, int32_t sourceLength,
+                     UErrorCode *pErrorCode) {
+    UChar pivotBuffer[CHUNK_SIZE];
+    UChar *pivot, *pivot2;
+
+    char *myTarget;
+    const char *sourceLimit;
+    const char *targetLimit;
+    int32_t targetLength=0;
+
+    /* set up */
+    if(sourceLength<0) {
+        sourceLimit=uprv_strchr(source, 0);
+    } else {
+        sourceLimit=source+sourceLength;
+    }
+
+    /* if there is no input data, we're done */
+    if(source==sourceLimit) {
+        return u_terminateChars(target, targetCapacity, 0, pErrorCode);
+    }
+
+    pivot=pivot2=pivotBuffer;
+    myTarget=target;
+    targetLength=0;
+
+    if(targetCapacity>0) {
+        /* perform real conversion */
+        targetLimit=target+targetCapacity;
+        ucnv_convertEx(outConverter, inConverter,
+                       &myTarget, targetLimit,
+                       &source, sourceLimit,
+                       pivotBuffer, &pivot, &pivot2, pivotBuffer+CHUNK_SIZE,
+                       FALSE,
+                       TRUE,
+                       pErrorCode);
+        targetLength=(int32_t)(myTarget-target);
+    }
+
+    /*
+     * If the output buffer is exhausted (or we are only "preflighting"), we need to stop writing
+     * to it but continue the conversion in order to store in targetCapacity
+     * the number of bytes that was required.
+     */
+    if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR || targetCapacity==0)
+    {
+        char targetBuffer[CHUNK_SIZE];
+
+        targetLimit=targetBuffer+CHUNK_SIZE;
+        do {
+            *pErrorCode=U_ZERO_ERROR;
+            myTarget=targetBuffer;
+            ucnv_convertEx(outConverter, inConverter,
+                           &myTarget, targetLimit,
+                           &source, sourceLimit,
+                           pivotBuffer, &pivot, &pivot2, pivotBuffer+CHUNK_SIZE,
+                           FALSE,
+                           TRUE,
+                           pErrorCode);
+            targetLength+=(int32_t)(myTarget-targetBuffer);
+        } while(*pErrorCode==U_BUFFER_OVERFLOW_ERROR);
+
+        /* done with preflighting, set warnings and errors as appropriate */
+        return u_terminateChars(target, targetCapacity, targetLength, pErrorCode);
+    }
+
+    /* no need to call u_terminateChars() because ucnv_convertEx() took care of that */
+    return targetLength;
+}
+
+U_CAPI int32_t U_EXPORT2
+ucnv_convert(const char *toConverterName, const char *fromConverterName,
+             char *target, int32_t targetCapacity,
+             const char *source, int32_t sourceLength,
+             UErrorCode *pErrorCode) {
+    UConverter in, out; /* stack-allocated */
+    UConverter *inConverter, *outConverter;
+    int32_t targetLength;
+
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    if( source==NULL || sourceLength<-1 ||
+        targetCapacity<0 || (targetCapacity>0 && target==NULL)
+    ) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    /* if there is no input data, we're done */
+    if(sourceLength==0 || (sourceLength<0 && *source==0)) {
+        return u_terminateChars(target, targetCapacity, 0, pErrorCode);
+    }
+
+    /* create the converters */
+    inConverter=ucnv_createConverter(&in, fromConverterName, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    outConverter=ucnv_createConverter(&out, toConverterName, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        ucnv_close(inConverter);
+        return 0;
+    }
+
+    targetLength=ucnv_internalConvert(outConverter, inConverter,
+                                      target, targetCapacity,
+                                      source, sourceLength,
+                                      pErrorCode);
+
+    ucnv_close(inConverter);
+    ucnv_close(outConverter);
+
+    return targetLength;
+}
+
+/* @internal */
+static int32_t
+ucnv_convertAlgorithmic(UBool convertToAlgorithmic,
+                        UConverterType algorithmicType,
+                        UConverter *cnv,
+                        char *target, int32_t targetCapacity,
+                        const char *source, int32_t sourceLength,
+                        UErrorCode *pErrorCode) {
+    UConverter algoConverterStatic; /* stack-allocated */
+    UConverter *algoConverter, *to, *from;
+    int32_t targetLength;
+
+    if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    if( cnv==NULL || source==NULL || sourceLength<-1 ||
+        targetCapacity<0 || (targetCapacity>0 && target==NULL)
+    ) {
+        *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    /* if there is no input data, we're done */
+    if(sourceLength==0 || (sourceLength<0 && *source==0)) {
+        return u_terminateChars(target, targetCapacity, 0, pErrorCode);
+    }
+
+    /* create the algorithmic converter */
+    algoConverter=ucnv_createAlgorithmicConverter(&algoConverterStatic, algorithmicType,
+                                                  "", 0, pErrorCode);
+    if(U_FAILURE(*pErrorCode)) {
+        return 0;
+    }
+
+    /* reset the other converter */
+    if(convertToAlgorithmic) {
+        /* cnv->Unicode->algo */
+        ucnv_resetToUnicode(cnv);
+        to=algoConverter;
+        from=cnv;
+    } else {
+        /* algo->Unicode->cnv */
+        ucnv_resetFromUnicode(cnv);
+        from=algoConverter;
+        to=cnv;
+    }
+
+    targetLength=ucnv_internalConvert(to, from,
+                                      target, targetCapacity,
+                                      source, sourceLength,
+                                      pErrorCode);
+
+    ucnv_close(algoConverter);
+
+    return targetLength;
+}
+
+U_CAPI int32_t U_EXPORT2
+ucnv_toAlgorithmic(UConverterType algorithmicType,
+                   UConverter *cnv,
+                   char *target, int32_t targetCapacity,
+                   const char *source, int32_t sourceLength,
+                   UErrorCode *pErrorCode) {
+    return ucnv_convertAlgorithmic(TRUE, algorithmicType, cnv,
+                                   target, targetCapacity,
+                                   source, sourceLength,
+                                   pErrorCode);
+}
+
+U_CAPI int32_t U_EXPORT2
+ucnv_fromAlgorithmic(UConverter *cnv,
+                     UConverterType algorithmicType,
+                     char *target, int32_t targetCapacity,
+                     const char *source, int32_t sourceLength,
+                     UErrorCode *pErrorCode) {
+    return ucnv_convertAlgorithmic(FALSE, algorithmicType, cnv,
+                                   target, targetCapacity,
+                                   source, sourceLength,
+                                   pErrorCode);
+}
+
+U_CAPI UConverterType  U_EXPORT2
+ucnv_getType(const UConverter* converter)
+{
+    int8_t type = converter->sharedData->staticData->conversionType;
+#if !UCONFIG_NO_LEGACY_CONVERSION
+    if(type == UCNV_MBCS) {
+        return ucnv_MBCSGetType(converter);
+    }
+#endif
+    return (UConverterType)type;
+}
+
+U_CAPI void  U_EXPORT2
+ucnv_getStarters(const UConverter* converter, 
+                 UBool starters[256],
+                 UErrorCode* err)
+{
+    if (err == NULL || U_FAILURE(*err)) {
+        return;
+    }
+
+    if(converter->sharedData->impl->getStarters != NULL) {
+        converter->sharedData->impl->getStarters(converter, starters, err);
+    } else {
+        *err = U_ILLEGAL_ARGUMENT_ERROR;
+    }
+}
+
+static const UAmbiguousConverter *ucnv_getAmbiguous(const UConverter *cnv)
+{
+    UErrorCode errorCode;
+    const char *name;
+    int32_t i;
+
+    if(cnv==NULL) {
+        return NULL;
+    }
+
+    errorCode=U_ZERO_ERROR;
+    name=ucnv_getName(cnv, &errorCode);
+    if(U_FAILURE(errorCode)) {
+        return NULL;
+    }
+
+    for(i=0; i<(int32_t)(sizeof(ambiguousConverters)/sizeof(UAmbiguousConverter)); ++i)
+    {
+        if(0==uprv_strcmp(name, ambiguousConverters[i].name))
+        {
+            return ambiguousConverters+i;
+        }
+    }
+
+    return NULL;
+}
+
+U_CAPI void  U_EXPORT2
+ucnv_fixFileSeparator(const UConverter *cnv, 
+                      UChar* source, 
+                      int32_t sourceLength) {
+    const UAmbiguousConverter *a;
+    int32_t i;
+    UChar variant5c;
+
+    if(cnv==NULL || source==NULL || sourceLength<=0 || (a=ucnv_getAmbiguous(cnv))==NULL)
+    {
+        return;
+    }
+
+    variant5c=a->variant5c;
+    for(i=0; i<sourceLength; ++i) {
+        if(source[i]==variant5c) {
+            source[i]=0x5c;
+        }
+    }
+}
+
+U_CAPI UBool  U_EXPORT2
+ucnv_isAmbiguous(const UConverter *cnv) {
+    return (UBool)(ucnv_getAmbiguous(cnv)!=NULL);
+}
+
+U_CAPI void  U_EXPORT2
+ucnv_setFallback(UConverter *cnv, UBool usesFallback)
+{
+    cnv->useFallback = usesFallback;
+}
+
+U_CAPI UBool  U_EXPORT2
+ucnv_usesFallback(const UConverter *cnv)
+{
+    return cnv->useFallback;
+}
+
+U_CAPI void  U_EXPORT2
+ucnv_getInvalidChars (const UConverter * converter,
+                      char *errBytes,
+                      int8_t * len,
+                      UErrorCode * err)
+{
+    if (err == NULL || U_FAILURE(*err))
+    {
+        return;
+    }
+    if (len == NULL || errBytes == NULL || converter == NULL)
+    {
+        *err = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    if (*len < converter->invalidCharLength)
+    {
+        *err = U_INDEX_OUTOFBOUNDS_ERROR;
+        return;
+    }
+    if ((*len = converter->invalidCharLength) > 0)
+    {
+        uprv_memcpy (errBytes, converter->invalidCharBuffer, *len);
+    }
+}
+
+U_CAPI void  U_EXPORT2
+ucnv_getInvalidUChars (const UConverter * converter,
+                       UChar *errChars,
+                       int8_t * len,
+                       UErrorCode * err)
+{
+    if (err == NULL || U_FAILURE(*err))
+    {
+        return;
+    }
+    if (len == NULL || errChars == NULL || converter == NULL)
+    {
+        *err = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    if (*len < converter->invalidUCharLength)
+    {
+        *err = U_INDEX_OUTOFBOUNDS_ERROR;
+        return;
+    }
+    if ((*len = converter->invalidUCharLength) > 0)
+    {
+        uprv_memcpy (errChars, converter->invalidUCharBuffer, sizeof(UChar) * (*len));
+    }
+}
+
+#define SIG_MAX_LEN 5
+
+U_CAPI const char* U_EXPORT2
+ucnv_detectUnicodeSignature( const char* source,
+                             int32_t sourceLength,
+                             int32_t* signatureLength,
+                             UErrorCode* pErrorCode) {
+    int32_t dummy;
+
+    /* initial 0xa5 bytes: make sure that if we read <SIG_MAX_LEN
+     * bytes we don't misdetect something 
+     */
+    char start[SIG_MAX_LEN]={ '\xa5', '\xa5', '\xa5', '\xa5', '\xa5' };
+    int i = 0;
+
+    if((pErrorCode==NULL) || U_FAILURE(*pErrorCode)){
+        return NULL;
+    }
+    
+    if(source == NULL || sourceLength < -1){
+        *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return NULL;
+    }
+
+    if(signatureLength == NULL) {
+        signatureLength = &dummy;
+    }
+
+    if(sourceLength==-1){
+        sourceLength=(int32_t)uprv_strlen(source);
+    }
+
+    
+    while(i<sourceLength&& i<SIG_MAX_LEN){
+        start[i]=source[i];
+        i++;
+    }
+
+    if(start[0] == '\xFE' && start[1] == '\xFF') {
+        *signatureLength=2;
+        return  "UTF-16BE";
+    } else if(start[0] == '\xFF' && start[1] == '\xFE') {
+        if(start[2] == '\x00' && start[3] =='\x00') {
+            *signatureLength=4;
+            return "UTF-32LE";
+        } else {
+            *signatureLength=2;
+            return  "UTF-16LE";
+        }
+    } else if(start[0] == '\xEF' && start[1] == '\xBB' && start[2] == '\xBF') {
+        *signatureLength=3;
+        return  "UTF-8";
+    } else if(start[0] == '\x00' && start[1] == '\x00' && 
+              start[2] == '\xFE' && start[3]=='\xFF') {
+        *signatureLength=4;
+        return  "UTF-32BE";
+    } else if(start[0] == '\x0E' && start[1] == '\xFE' && start[2] == '\xFF') {
+        *signatureLength=3;
+        return "SCSU";
+    } else if(start[0] == '\xFB' && start[1] == '\xEE' && start[2] == '\x28') {
+        *signatureLength=3;
+        return "BOCU-1";
+    } else if(start[0] == '\x2B' && start[1] == '\x2F' && start[2] == '\x76') {
+        /*
+         * UTF-7: Initial U+FEFF is encoded as +/v8  or  +/v9  or  +/v+  or  +/v/
+         * depending on the second UTF-16 code unit.
+         * Detect the entire, closed Unicode mode sequence +/v8- for only U+FEFF
+         * if it occurs.
+         *
+         * So far we have +/v
+         */
+        if(start[3] == '\x38' && start[4] == '\x2D') {
+            /* 5 bytes +/v8- */
+            *signatureLength=5;
+            return "UTF-7";
+        } else if(start[3] == '\x38' || start[3] == '\x39' || start[3] == '\x2B' || start[3] == '\x2F') {
+            /* 4 bytes +/v8  or  +/v9  or  +/v+  or  +/v/ */
+            *signatureLength=4;
+            return "UTF-7";
+        }
+    }else if(start[0]=='\xDD' && start[1]== '\x73'&& start[2]=='\x66' && start[3]=='\x73'){
+        *signatureLength=4;
+        return "UTF-EBCDIC";
+    }
+
+
+    /* no known Unicode signature byte sequence recognized */
+    *signatureLength=0;
+    return NULL;
+}
+
+U_CAPI int32_t U_EXPORT2
+ucnv_fromUCountPending(const UConverter* cnv, UErrorCode* status)
+{
+    if(status == NULL || U_FAILURE(*status)){
+        return -1;
+    }
+    if(cnv == NULL){
+        *status = U_ILLEGAL_ARGUMENT_ERROR;
+        return -1;
+    }
+
+    if(cnv->preFromULength > 0){
+        return U16_LENGTH(cnv->preFromUFirstCP)+cnv->preFromULength ;
+    }else if(cnv->preFromULength < 0){
+        return -cnv->preFromULength ;
+    }else if(cnv->fromUChar32 > 0){
+        return 1;
+    }else if(cnv->preFromUFirstCP >0){
+        return U16_LENGTH(cnv->preFromUFirstCP);
+    }
+    return 0; 
+
+}
+
+U_CAPI int32_t U_EXPORT2
+ucnv_toUCountPending(const UConverter* cnv, UErrorCode* status){
+
+    if(status == NULL || U_FAILURE(*status)){
+        return -1;
+    }
+    if(cnv == NULL){
+        *status = U_ILLEGAL_ARGUMENT_ERROR;
+        return -1;
+    }
+
+    if(cnv->preToULength > 0){
+        return cnv->preToULength ;
+    }else if(cnv->preToULength < 0){
+        return -cnv->preToULength;
+    }else if(cnv->toULength > 0){
+        return cnv->toULength;
+    }
+    return 0;
+}
+#endif
+
+/*
+ * Hey, Emacs, please set the following:
+ *
+ * Local Variables:
+ * indent-tabs-mode: nil
+ * End:
+ *
+ */
diff --git a/icu/source/common/ucnv2022.c b/icu/source/common/ucnv2022.c
new file mode 100644
index 0000000..5c03446
--- /dev/null
+++ b/icu/source/common/ucnv2022.c
@@ -0,0 +1,3910 @@
+/*
+**********************************************************************
+*   Copyright (C) 2000-2009, International Business Machines
+*   Corporation and others.  All Rights Reserved.
+**********************************************************************
+*   file name:  ucnv2022.c
+*   encoding:   US-ASCII
+*   tab size:   8 (not used)
+*   indentation:4
+*
+*   created on: 2000feb03
+*   created by: Markus W. Scherer
+*
+*   Change history:
+*
+*   06/29/2000  helena  Major rewrite of the callback APIs.
+*   08/08/2000  Ram     Included support for ISO-2022-JP-2
+*                       Changed implementation of toUnicode
+*                       function
+*   08/21/2000  Ram     Added support for ISO-2022-KR
+*   08/29/2000  Ram     Seperated implementation of EBCDIC to
+*                       ucnvebdc.c
+*   09/20/2000  Ram     Added support for ISO-2022-CN
+*                       Added implementations for getNextUChar()
+*                       for specific 2022 country variants.
+*   10/31/2000  Ram     Implemented offsets logic functions
+*/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_CONVERSION && !UCONFIG_NO_LEGACY_CONVERSION
+
+#include "unicode/ucnv.h"
+#include "unicode/uset.h"
+#include "unicode/ucnv_err.h"
+#include "unicode/ucnv_cb.h"
+#include "ucnv_imp.h"
+#include "ucnv_bld.h"
+#include "ucnv_cnv.h"
+#include "ucnvmbcs.h"
+#include "cstring.h"
+#include "cmemory.h"
+
+#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
+
+#ifdef U_ENABLE_GENERIC_ISO_2022
+/*
+ * I am disabling the generic ISO-2022 converter after proposing to do so on
+ * the icu mailing list two days ago.
+ *
+ * Reasons:
+ * 1. It does not fully support the ISO-2022/ECMA-35 specification with all of
+ *    its designation sequences, single shifts with return to the previous state,
+ *    switch-with-no-return to UTF-16BE or similar, etc.
+ *    This is unlike the language-specific variants like ISO-2022-JP which
+ *    require a much smaller repertoire of ISO-2022 features.
+ *    These variants continue to be supported.
+ * 2. I believe that no one is really using the generic ISO-2022 converter
+ *    but rather always one of the language-specific variants.
+ *    Note that ICU's generic ISO-2022 converter has always output one escape
+ *    sequence followed by UTF-8 for the whole stream.
+ * 3. Switching between subcharsets is extremely slow, because each time
+ *    the previous converter is closed and a new one opened,
+ *    without any kind of caching, least-recently-used list, etc.
+ * 4. The code is currently buggy, and given the above it does not seem
+ *    reasonable to spend the time on maintenance.
+ * 5. ISO-2022 subcharsets should normally be used with 7-bit byte encodings.
+ *    This means, for example, that when ISO-8859-7 is designated, the following
+ *    ISO-2022 bytes 00..7f should be interpreted as ISO-8859-7 bytes 80..ff.
+ *    The ICU ISO-2022 converter does not handle this - and has no information
+ *    about which subconverter would have to be shifted vs. which is designed
+ *    for 7-bit ISO-2022.
+ *
+ * Markus Scherer 2003-dec-03
+ */
+#endif
+
+static const char SHIFT_IN_STR[]  = "\x0F";
+static const char SHIFT_OUT_STR[] = "\x0E";
+
+#define CR      0x0D
+#define LF      0x0A
+#define H_TAB   0x09
+#define V_TAB   0x0B
+#define SPACE   0x20
+
+enum {
+    HWKANA_START=0xff61,
+    HWKANA_END=0xff9f
+};
+
+/*
+ * 94-character sets with native byte values A1..FE are encoded in ISO 2022
+ * as bytes 21..7E. (Subtract 0x80.)
+ * 96-character sets with native byte values A0..FF are encoded in ISO 2022
+ * as bytes 20..7F. (Subtract 0x80.)
+ * Do not encode C1 control codes with native bytes 80..9F
+ * as bytes 00..1F (C0 control codes).
+ */
+enum {
+    GR94_START=0xa1,
+    GR94_END=0xfe,
+    GR96_START=0xa0,
+    GR96_END=0xff
+};
+
+/*
+ * ISO 2022 control codes must not be converted from Unicode
+ * because they would mess up the byte stream.
+ * The bit mask 0x0800c000 has bits set at bit positions 0xe, 0xf, 0x1b
+ * corresponding to SO, SI, and ESC.
+ */
+#define IS_2022_CONTROL(c) (((c)<0x20) && (((uint32_t)1<<(c))&0x0800c000)!=0)
+
+/* for ISO-2022-JP and -CN implementations */
+typedef enum  {
+        /* shared values */
+        INVALID_STATE=-1,
+        ASCII = 0,
+
+        SS2_STATE=0x10,
+        SS3_STATE,
+
+        /* JP */
+        ISO8859_1 = 1 ,
+        ISO8859_7 = 2 ,
+        JISX201  = 3,
+        JISX208 = 4,
+        JISX212 = 5,
+        GB2312  =6,
+        KSC5601 =7,
+        HWKANA_7BIT=8,    /* Halfwidth Katakana 7 bit */
+
+        /* CN */
+        /* the first few enum constants must keep their values because they correspond to myConverterArray[] */
+        GB2312_1=1,
+        ISO_IR_165=2,
+        CNS_11643=3,
+
+        /*
+         * these are used in StateEnum and ISO2022State variables,
+         * but CNS_11643 must be used to index into myConverterArray[]
+         */
+        CNS_11643_0=0x20,
+        CNS_11643_1,
+        CNS_11643_2,
+        CNS_11643_3,
+        CNS_11643_4,
+        CNS_11643_5,
+        CNS_11643_6,
+        CNS_11643_7
+} StateEnum;
+
+/* is the StateEnum charset value for a DBCS charset? */
+#define IS_JP_DBCS(cs) (JISX208<=(cs) && (cs)<=KSC5601)
+
+#define CSM(cs) ((uint16_t)1<<(cs))
+
+/*
+ * Each of these charset masks (with index x) contains a bit for a charset in exact correspondence
+ * to whether that charset is used in the corresponding version x of ISO_2022,locale=ja,version=x
+ *
+ * Note: The converter uses some leniency:
+ * - The escape sequence ESC ( I for half-width 7-bit Katakana is recognized in
+ *   all versions, not just JIS7 and JIS8.
+ * - ICU does not distinguish between different versions of JIS X 0208.
+ */
+enum { MAX_JA_VERSION=4 };
+static const uint16_t jpCharsetMasks[MAX_JA_VERSION+1]={
+    CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT),
+    CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT)|CSM(JISX212),
+    CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT)|CSM(JISX212)|CSM(GB2312)|CSM(KSC5601)|CSM(ISO8859_1)|CSM(ISO8859_7),
+    CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT)|CSM(JISX212)|CSM(GB2312)|CSM(KSC5601)|CSM(ISO8859_1)|CSM(ISO8859_7),
+    CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT)|CSM(JISX212)|CSM(GB2312)|CSM(KSC5601)|CSM(ISO8859_1)|CSM(ISO8859_7)
+};
+
+typedef enum {
+        ASCII1=0,
+        LATIN1,
+        SBCS,
+        DBCS,
+        MBCS,
+        HWKANA
+}Cnv2022Type;
+
+typedef struct ISO2022State {
+    int8_t cs[4];       /* charset number for SI (G0)/SO (G1)/SS2 (G2)/SS3 (G3) */
+    int8_t g;           /* 0..3 for G0..G3 (SI/SO/SS2/SS3) */
+    int8_t prevG;       /* g before single shift (SS2 or SS3) */
+} ISO2022State;
+
+#define UCNV_OPTIONS_VERSION_MASK 0xf
+#define UCNV_2022_MAX_CONVERTERS 10
+
+typedef struct{
+    UConverterSharedData *myConverterArray[UCNV_2022_MAX_CONVERTERS];
+    UConverter *currentConverter;
+    Cnv2022Type currentType;
+    ISO2022State toU2022State, fromU2022State;
+    uint32_t key;
+    uint32_t version;
+#ifdef U_ENABLE_GENERIC_ISO_2022
+    UBool isFirstBuffer;
+#endif
+    UBool isEmptySegment;
+    char name[30];
+    char locale[3];
+}UConverterDataISO2022;
+
+/* Protos */
+/* ISO-2022 ----------------------------------------------------------------- */
+
+/*Forward declaration */
+U_CFUNC void
+ucnv_fromUnicode_UTF8(UConverterFromUnicodeArgs * args,
+                      UErrorCode * err);
+U_CFUNC void
+ucnv_fromUnicode_UTF8_OFFSETS_LOGIC(UConverterFromUnicodeArgs * args,
+                                    UErrorCode * err);
+
+#define ESC_2022 0x1B /*ESC*/
+
+typedef enum
+{
+        INVALID_2022 = -1, /*Doesn't correspond to a valid iso 2022 escape sequence*/
+        VALID_NON_TERMINAL_2022 = 0, /*so far corresponds to a valid iso 2022 escape sequence*/
+        VALID_TERMINAL_2022 = 1, /*corresponds to a valid iso 2022 escape sequence*/
+        VALID_MAYBE_TERMINAL_2022 = 2 /*so far matches one iso 2022 escape sequence, but by adding more characters might match another escape sequence*/
+} UCNV_TableStates_2022;
+
+/*
+* The way these state transition arrays work is:
+* ex : ESC$B is the sequence for JISX208
+*      a) First Iteration: char is ESC
+*          i) Get the value of ESC from normalize_esq_chars_2022[] with int value of ESC as index
+*             int x = normalize_esq_chars_2022[27] which is equal to 1
+*         ii) Search for this value in escSeqStateTable_Key_2022[]
+*             value of x is stored at escSeqStateTable_Key_2022[0]
+*        iii) Save this index as offset
+*         iv) Get state of this sequence from escSeqStateTable_Value_2022[]
+*             escSeqStateTable_Value_2022[offset], which is VALID_NON_TERMINAL_2022
+*     b) Switch on this state and continue to next char
+*          i) Get the value of $ from normalize_esq_chars_2022[] with int value of $ as index
+*             which is normalize_esq_chars_2022[36] == 4
+*         ii) x is currently 1(from above)
+*               x<<=5 -- x is now 32
+*               x+=normalize_esq_chars_2022[36]
+*               now x is 36
+*        iii) Search for this value in escSeqStateTable_Key_2022[]
+*             value of x is stored at escSeqStateTable_Key_2022[2], so offset is 2
+*         iv) Get state of this sequence from escSeqStateTable_Value_2022[]
+*             escSeqStateTable_Value_2022[offset], which is VALID_NON_TERMINAL_2022
+*     c) Switch on this state and continue to next char
+*        i)  Get the value of B from normalize_esq_chars_2022[] with int value of B as index
+*        ii) x is currently 36 (from above)
+*            x<<=5 -- x is now 1152
+*            x+=normalize_esq_chars_2022[66]
+*            now x is 1161
+*       iii) Search for this value in escSeqStateTable_Key_2022[]
+*            value of x is stored at escSeqStateTable_Key_2022[21], so offset is 21
+*        iv) Get state of this sequence from escSeqStateTable_Value_2022[21]
+*            escSeqStateTable_Value_2022[offset], which is VALID_TERMINAL_2022
+*         v) Get the converter name form escSeqStateTable_Result_2022[21] which is JISX208
+*/
+
+
+/*Below are the 3 arrays depicting a state transition table*/
+static const int8_t normalize_esq_chars_2022[256] = {
+/*       0      1       2       3       4      5       6        7       8       9           */
+
+         0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,1      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,4      ,7      ,29      ,0
+        ,2     ,24     ,26     ,27     ,0      ,3      ,23     ,6      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,5      ,8      ,9      ,10     ,11     ,12
+        ,13    ,14     ,15     ,16     ,17     ,18     ,19     ,20     ,25     ,28
+        ,0     ,0      ,21     ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,22    ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0      ,0
+        ,0     ,0      ,0      ,0      ,0      ,0
+};
+
+#ifdef U_ENABLE_GENERIC_ISO_2022
+/*
+ * When the generic ISO-2022 converter is completely removed, not just disabled
+ * per #ifdef, then the following state table and the associated tables that are
+ * dimensioned with MAX_STATES_2022 should be trimmed.
+ *
+ * Especially, VALID_MAYBE_TERMINAL_2022 will not be used any more, and all of
+ * the associated escape sequences starting with ESC ( B should be removed.
+ * This includes the ones with key values 1097 and all of the ones above 1000000.
+ *
+ * For the latter, the tables can simply be truncated.
+ * For the former, since the tables must be kept parallel, it is probably best
+ * to simply duplicate an adjacent table cell, parallel in all tables.
+ *
+ * It may make sense to restructure the tables, especially by using small search
+ * tables for the variants instead of indexing them parallel to the table here.
+ */
+#endif
+
+#define MAX_STATES_2022 74
+static const int32_t escSeqStateTable_Key_2022[MAX_STATES_2022] = {
+/*   0           1           2           3           4           5           6           7           8           9           */
+
+     1          ,34         ,36         ,39         ,55         ,57         ,60         ,61         ,1093       ,1096
+    ,1097       ,1098       ,1099       ,1100       ,1101       ,1102       ,1103       ,1104       ,1105       ,1106
+    ,1109       ,1154       ,1157       ,1160       ,1161       ,1176       ,1178       ,1179       ,1254       ,1257
+    ,1768       ,1773       ,1957       ,35105      ,36933      ,36936      ,36937      ,36938      ,36939      ,36940
+    ,36942      ,36943      ,36944      ,36945      ,36946      ,36947      ,36948      ,37640      ,37642      ,37644
+    ,37646      ,37711      ,37744      ,37745      ,37746      ,37747      ,37748      ,40133      ,40136      ,40138
+    ,40139      ,40140      ,40141      ,1123363    ,35947624   ,35947625   ,35947626   ,35947627   ,35947629   ,35947630
+    ,35947631   ,35947635   ,35947636   ,35947638
+};
+
+#ifdef U_ENABLE_GENERIC_ISO_2022
+
+static const char* const escSeqStateTable_Result_2022[MAX_STATES_2022] = {
+ /*  0                      1                        2                      3                   4                   5                        6                      7                       8                       9    */
+
+     NULL                   ,NULL                   ,NULL                   ,NULL               ,NULL               ,NULL                   ,NULL                   ,NULL                   ,"latin1"               ,"latin1"
+    ,"latin1"               ,"ibm-865"              ,"ibm-865"              ,"ibm-865"          ,"ibm-865"          ,"ibm-865"              ,"ibm-865"              ,"JISX0201"             ,"JISX0201"             ,"latin1"
+    ,"latin1"               ,NULL                   ,"JISX-208"             ,"ibm-5478"         ,"JISX-208"         ,NULL                   ,NULL                   ,NULL                   ,NULL                   ,"UTF8"
+    ,"ISO-8859-1"           ,"ISO-8859-7"           ,"JIS-X-208"            ,NULL               ,"ibm-955"          ,"ibm-367"              ,"ibm-952"              ,"ibm-949"              ,"JISX-212"             ,"ibm-1383"
+    ,"ibm-952"              ,"ibm-964"              ,"ibm-964"              ,"ibm-964"          ,"ibm-964"          ,"ibm-964"              ,"ibm-964"              ,"ibm-5478"         ,"ibm-949"              ,"ISO-IR-165"
+    ,"CNS-11643-1992,1"     ,"CNS-11643-1992,2"     ,"CNS-11643-1992,3"     ,"CNS-11643-1992,4" ,"CNS-11643-1992,5" ,"CNS-11643-1992,6"     ,"CNS-11643-1992,7"     ,"UTF16_PlatformEndian" ,"UTF16_PlatformEndian" ,"UTF16_PlatformEndian"
+    ,"UTF16_PlatformEndian" ,"UTF16_PlatformEndian" ,"UTF16_PlatformEndian" ,NULL               ,"latin1"           ,"ibm-912"              ,"ibm-913"              ,"ibm-914"              ,"ibm-813"              ,"ibm-1089"
+    ,"ibm-920"              ,"ibm-915"              ,"ibm-915"              ,"latin1"
+};
+
+#endif
+
+static const int8_t escSeqStateTable_Value_2022[MAX_STATES_2022] = {
+/*          0                           1                         2                             3                           4                           5                               6                        7                          8                           9       */
+     VALID_NON_TERMINAL_2022    ,VALID_NON_TERMINAL_2022    ,VALID_NON_TERMINAL_2022    ,VALID_NON_TERMINAL_2022     ,VALID_NON_TERMINAL_2022   ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_NON_TERMINAL_2022    ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022
+    ,VALID_MAYBE_TERMINAL_2022  ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022
+    ,VALID_TERMINAL_2022        ,VALID_NON_TERMINAL_2022    ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_NON_TERMINAL_2022    ,VALID_NON_TERMINAL_2022    ,VALID_NON_TERMINAL_2022    ,VALID_NON_TERMINAL_2022    ,VALID_TERMINAL_2022
+    ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_NON_TERMINAL_2022    ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022
+    ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022
+    ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022
+    ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_NON_TERMINAL_2022    ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022
+    ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022        ,VALID_TERMINAL_2022
+};
+
+
+/* Type def for refactoring changeState_2022 code*/
+typedef enum{
+#ifdef U_ENABLE_GENERIC_ISO_2022
+    ISO_2022=0,
+#endif
+    ISO_2022_JP=1,
+    ISO_2022_KR=2,
+    ISO_2022_CN=3
+} Variant2022;
+
+/*********** ISO 2022 Converter Protos ***********/
+static void
+_ISO2022Open(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode);
+
+static void
+ _ISO2022Close(UConverter *converter);
+
+static void
+_ISO2022Reset(UConverter *converter, UConverterResetChoice choice);
+
+static const char*
+_ISO2022getName(const UConverter* cnv);
+
+static void
+_ISO_2022_WriteSub(UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorCode *err);
+
+static UConverter *
+_ISO_2022_SafeClone(const UConverter *cnv, void *stackBuffer, int32_t *pBufferSize, UErrorCode *status);
+
+#ifdef U_ENABLE_GENERIC_ISO_2022
+static void
+T_UConverter_toUnicode_ISO_2022_OFFSETS_LOGIC(UConverterToUnicodeArgs* args, UErrorCode* err);
+#endif
+
+/*const UConverterSharedData _ISO2022Data;*/
+static const UConverterSharedData _ISO2022JPData;
+static const UConverterSharedData _ISO2022KRData;
+static const UConverterSharedData _ISO2022CNData;
+
+/*************** Converter implementations ******************/
+
+/* The purpose of this function is to get around gcc compiler warnings. */
+static U_INLINE void
+fromUWriteUInt8(UConverter *cnv,
+                 const char *bytes, int32_t length,
+                 uint8_t **target, const char *targetLimit,
+                 int32_t **offsets,
+                 int32_t sourceIndex,
+                 UErrorCode *pErrorCode)
+{
+    char *targetChars = (char *)*target;
+    ucnv_fromUWriteBytes(cnv, bytes, length, &targetChars, targetLimit,
+                         offsets, sourceIndex, pErrorCode);
+    *target = (uint8_t*)targetChars;
+
+}
+
+static U_INLINE void
+setInitialStateToUnicodeKR(UConverter* converter, UConverterDataISO2022 *myConverterData){
+    if(myConverterData->version == 1) {
+        UConverter *cnv = myConverterData->currentConverter;
+
+        cnv->toUnicodeStatus=0;     /* offset */
+        cnv->mode=0;                /* state */
+        cnv->toULength=0;           /* byteIndex */
+    }
+}
+
+static U_INLINE void
+setInitialStateFromUnicodeKR(UConverter* converter,UConverterDataISO2022 *myConverterData){
+   /* in ISO-2022-KR the designator sequence appears only once
+    * in a file so we append it only once
+    */
+    if( converter->charErrorBufferLength==0){
+
+        converter->charErrorBufferLength = 4;
+        converter->charErrorBuffer[0] = 0x1b;
+        converter->charErrorBuffer[1] = 0x24;
+        converter->charErrorBuffer[2] = 0x29;
+        converter->charErrorBuffer[3] = 0x43;
+    }
+    if(myConverterData->version == 1) {
+        UConverter *cnv = myConverterData->currentConverter;
+
+        cnv->fromUChar32=0;
+        cnv->fromUnicodeStatus=1;   /* prevLength */
+    }
+}
+
+static void
+_ISO2022Open(UConverter *cnv, UConverterLoadArgs *pArgs, UErrorCode *errorCode){
+
+    char myLocale[6]={' ',' ',' ',' ',' ',' '};
+
+    cnv->extraInfo = uprv_malloc (sizeof (UConverterDataISO2022));
+    if(cnv->extraInfo != NULL) {
+        UConverterNamePieces stackPieces;
+        UConverterLoadArgs stackArgs={ (int32_t)sizeof(UConverterLoadArgs) };
+        UConverterDataISO2022 *myConverterData=(UConverterDataISO2022 *) cnv->extraInfo;
+        uint32_t version;
+
+        stackArgs.onlyTestIsLoadable = pArgs->onlyTestIsLoadable;
+
+        uprv_memset(myConverterData, 0, sizeof(UConverterDataISO2022));
+        myConverterData->currentType = ASCII1;
+        cnv->fromUnicodeStatus =FALSE;
+        if(pArgs->locale){
+            uprv_strncpy(myLocale, pArgs->locale, sizeof(myLocale));
+        }
+        version = pArgs->options & UCNV_OPTIONS_VERSION_MASK;
+        myConverterData->version = version;
+        if(myLocale[0]=='j' && (myLocale[1]=='a'|| myLocale[1]=='p') &&
+            (myLocale[2]=='_' || myLocale[2]=='\0'))
+        {
+            size_t len=0;
+            /* open the required converters and cache them */
+            if(version>MAX_JA_VERSION) {
+                /* prevent indexing beyond jpCharsetMasks[] */
+                myConverterData->version = version = 0;
+            }
+            if(jpCharsetMasks[version]&CSM(ISO8859_7)) {
+                myConverterData->myConverterArray[ISO8859_7] =
+                    ucnv_loadSharedData("ISO8859_7", &stackPieces, &stackArgs, errorCode);
+            }
+            myConverterData->myConverterArray[JISX208] =
+                ucnv_loadSharedData("Shift-JIS", &stackPieces, &stackArgs, errorCode);
+            if(jpCharsetMasks[version]&CSM(JISX212)) {
+                myConverterData->myConverterArray[JISX212] =
+                    ucnv_loadSharedData("jisx-212", &stackPieces, &stackArgs, errorCode);
+            }
+            if(jpCharsetMasks[version]&CSM(GB2312)) {
+                myConverterData->myConverterArray[GB2312] =
+                    ucnv_loadSharedData("ibm-5478", &stackPieces, &stackArgs, errorCode);   /* gb_2312_80-1 */
+            }
+            if(jpCharsetMasks[version]&CSM(KSC5601)) {
+                myConverterData->myConverterArray[KSC5601] =
+                    ucnv_loadSharedData("ksc_5601", &stackPieces, &stackArgs, errorCode);
+            }
+
+            /* set the function pointers to appropriate funtions */
+            cnv->sharedData=(UConverterSharedData*)(&_ISO2022JPData);
+            uprv_strcpy(myConverterData->locale,"ja");
+
+            (void)uprv_strcpy(myConverterData->name,"ISO_2022,locale=ja,version=");
+            len = uprv_strlen(myConverterData->name);
+            myConverterData->name[len]=(char)(myConverterData->version+(int)'0');
+            myConverterData->name[len+1]='\0';
+        }
+        else if(myLocale[0]=='k' && (myLocale[1]=='o'|| myLocale[1]=='r') &&
+            (myLocale[2]=='_' || myLocale[2]=='\0'))
+        {
+            const char *cnvName;
+            if(version==1) {
+                cnvName="icu-internal-25546";
+            } else {
+                cnvName="ibm-949";
+                myConverterData->version=version=0;
+            }
+            if(pArgs->onlyTestIsLoadable) {
+                ucnv_canCreateConverter(cnvName, errorCode);  /* errorCode carries result */
+                uprv_free(cnv->extraInfo);
+                cnv->extraInfo=NULL;
+                return;
+            } else {
+                myConverterData->currentConverter=ucnv_open(cnvName, errorCode);
+                if (U_FAILURE(*errorCode)) {
+                    _ISO2022Close(cnv);
+                    return;
+                }
+
+                if(version==1) {
+                    (void)uprv_strcpy(myConverterData->name,"ISO_2022,locale=ko,version=1");
+                    uprv_memcpy(cnv->subChars, myConverterData->currentConverter->subChars, 4);
+                    cnv->subCharLen = myConverterData->currentConverter->subCharLen;
+                }else{
+                    (void)uprv_strcpy(myConverterData->name,"ISO_2022,locale=ko,version=0");
+                }
+
+                /* initialize the state variables */
+                setInitialStateToUnicodeKR(cnv, myConverterData);
+                setInitialStateFromUnicodeKR(cnv, myConverterData);
+
+                /* set the function pointers to appropriate funtions */
+                cnv->sharedData=(UConverterSharedData*)&_ISO2022KRData;
+                uprv_strcpy(myConverterData->locale,"ko");
+            }
+        }
+        else if(((myLocale[0]=='z' && myLocale[1]=='h') || (myLocale[0]=='c'&& myLocale[1]=='n'))&&
+            (myLocale[2]=='_' || myLocale[2]=='\0'))
+        {
+
+            /* open the required converters and cache them */
+            myConverterData->myConverterArray[GB2312_1] =
+                ucnv_loadSharedData("ibm-5478", &stackPieces, &stackArgs, errorCode);
+            if(version==1) {
+                myConverterData->myConverterArray[ISO_IR_165] =
+                    ucnv_loadSharedData("iso-ir-165", &stackPieces, &stackArgs, errorCode);
+            }
+            myConverterData->myConverterArray[CNS_11643] =
+                ucnv_loadSharedData("cns-11643-1992", &stackPieces, &stackArgs, errorCode);
+
+
+            /* set the function pointers to appropriate funtions */
+            cnv->sharedData=(UConverterSharedData*)&_ISO2022CNData;
+            uprv_strcpy(myConverterData->locale,"cn");
+
+            if (version==1){
+                (void)uprv_strcpy(myConverterData->name,"ISO_2022,locale=zh,version=1");
+            }else{
+                myConverterData->version = 0;
+                (void)uprv_strcpy(myConverterData->name,"ISO_2022,locale=zh,version=0");
+            }
+        }
+        else{
+#ifdef U_ENABLE_GENERIC_ISO_2022
+            myConverterData->isFirstBuffer = TRUE;
+
+            /* append the UTF-8 escape sequence */
+            cnv->charErrorBufferLength = 3;
+            cnv->charErrorBuffer[0] = 0x1b;
+            cnv->charErrorBuffer[1] = 0x25;
+            cnv->charErrorBuffer[2] = 0x42;
+
+            cnv->sharedData=(UConverterSharedData*)&_ISO2022Data;
+            /* initialize the state variables */
+            uprv_strcpy(myConverterData->name,"ISO_2022");
+#else
+            *errorCode = U_UNSUPPORTED_ERROR;
+            return;
+#endif
+        }
+
+        cnv->maxBytesPerUChar=cnv->sharedData->staticData->maxBytesPerChar;
+
+        if(U_FAILURE(*errorCode) || pArgs->onlyTestIsLoadable) {
+            _ISO2022Close(cnv);
+        }
+    } else {
+        *errorCode = U_MEMORY_ALLOCATION_ERROR;
+    }
+}
+
+
+static void
+_ISO2022Close(UConverter *converter) {
+    UConverterDataISO2022* myData =(UConverterDataISO2022 *) (converter->extraInfo);
+    UConverterSharedData **array = myData->myConverterArray;
+    int32_t i;
+
+    if (converter->extraInfo != NULL) {
+        /*close the array of converter pointers and free the memory*/
+        for (i=0; i<UCNV_2022_MAX_CONVERTERS; i++) {
+            if(array[i]!=NULL) {
+                ucnv_unloadSharedDataIfReady(array[i]);
+            }
+        }
+
+        ucnv_close(myData->currentConverter);
+
+        if(!converter->isExtraLocal){
+            uprv_free (converter->extraInfo);
+            converter->extraInfo = NULL;
+        }
+    }
+}
+
+static void
+_ISO2022Reset(UConverter *converter, UConverterResetChoice choice) {
+    UConverterDataISO2022 *myConverterData=(UConverterDataISO2022 *) (converter->extraInfo);
+    if(choice<=UCNV_RESET_TO_UNICODE) {
+        uprv_memset(&myConverterData->toU2022State, 0, sizeof(ISO2022State));
+        myConverterData->key = 0;
+        myConverterData->isEmptySegment = FALSE;
+    }
+    if(choice!=UCNV_RESET_TO_UNICODE) {
+        uprv_memset(&myConverterData->fromU2022State, 0, sizeof(ISO2022State));
+    }
+#ifdef U_ENABLE_GENERIC_ISO_2022
+    if(myConverterData->locale[0] == 0){
+        if(choice<=UCNV_RESET_TO_UNICODE) {
+            myConverterData->isFirstBuffer = TRUE;
+            myConverterData->key = 0;
+            if (converter->mode == UCNV_SO){
+                ucnv_close (myConverterData->currentConverter);
+                myConverterData->currentConverter=NULL;
+            }
+            converter->mode = UCNV_SI;
+        }
+        if(choice!=UCNV_RESET_TO_UNICODE) {
+            /* re-append UTF-8 escape sequence */
+            converter->charErrorBufferLength = 3;
+            converter->charErrorBuffer[0] = 0x1b;
+            converter->charErrorBuffer[1] = 0x28;
+            converter->charErrorBuffer[2] = 0x42;
+        }
+    }
+    else
+#endif
+    {
+        /* reset the state variables */
+        if(myConverterData->locale[0] == 'k'){
+            if(choice<=UCNV_RESET_TO_UNICODE) {
+                setInitialStateToUnicodeKR(converter, myConverterData);
+            }
+            if(choice!=UCNV_RESET_TO_UNICODE) {
+                setInitialStateFromUnicodeKR(converter, myConverterData);
+            }
+        }
+    }
+}
+
+static const char*
+_ISO2022getName(const UConverter* cnv){
+    if(cnv->extraInfo){
+        UConverterDataISO2022* myData= (UConverterDataISO2022*)cnv->extraInfo;
+        return myData->name;
+    }
+    return NULL;
+}
+
+
+/*************** to unicode *******************/
+/****************************************************************************
+ * Recognized escape sequences are
+ * <ESC>(B  ASCII
+ * <ESC>.A  ISO-8859-1
+ * <ESC>.F  ISO-8859-7
+ * <ESC>(J  JISX-201
+ * <ESC>(I  JISX-201
+ * <ESC>$B  JISX-208
+ * <ESC>$@  JISX-208
+ * <ESC>$(D JISX-212
+ * <ESC>$A  GB2312
+ * <ESC>$(C KSC5601
+ */
+static const int8_t nextStateToUnicodeJP[MAX_STATES_2022]= {
+/*      0                1               2               3               4               5               6               7               8               9    */
+    INVALID_STATE   ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,SS2_STATE      ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE
+    ,ASCII          ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,JISX201        ,HWKANA_7BIT    ,JISX201        ,INVALID_STATE
+    ,INVALID_STATE  ,INVALID_STATE  ,JISX208        ,GB2312         ,JISX208        ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE
+    ,ISO8859_1      ,ISO8859_7      ,JISX208        ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,KSC5601        ,JISX212        ,INVALID_STATE
+    ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE
+    ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE
+    ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE
+    ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE
+};
+
+/*************** to unicode *******************/
+static const int8_t nextStateToUnicodeCN[MAX_STATES_2022]= {
+/*      0                1               2               3               4               5               6               7               8               9    */
+     INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,SS2_STATE      ,SS3_STATE      ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE
+    ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE
+    ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE
+    ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE
+    ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,GB2312_1       ,INVALID_STATE  ,ISO_IR_165
+    ,CNS_11643_1    ,CNS_11643_2    ,CNS_11643_3    ,CNS_11643_4    ,CNS_11643_5    ,CNS_11643_6    ,CNS_11643_7    ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE
+    ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE
+    ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE  ,INVALID_STATE
+};
+
+
+static UCNV_TableStates_2022
+getKey_2022(char c,int32_t* key,int32_t* offset){
+    int32_t togo;
+    int32_t low = 0;
+    int32_t hi = MAX_STATES_2022;
+    int32_t oldmid=0;
+
+    togo = normalize_esq_chars_2022[(uint8_t)c];
+    if(togo == 0) {
+        /* not a valid character anywhere in an escape sequence */
+        *key = 0;
+        *offset = 0;
+        return INVALID_2022;
+    }
+    togo = (*key << 5) + togo;
+
+    while (hi != low)  /*binary search*/{
+
+        register int32_t mid = (hi+low) >> 1; /*Finds median*/
+
+        if (mid == oldmid)
+            break;
+
+        if (escSeqStateTable_Key_2022[mid] > togo){
+            hi = mid;
+        }
+        else if (escSeqStateTable_Key_2022[mid] < togo){
+            low = mid;
+        }
+        else /*we found it*/{
+            *key = togo;
+            *offset = mid;
+            return (UCNV_TableStates_2022)escSeqStateTable_Value_2022[mid];
+        }
+        oldmid = mid;
+
+    }
+
+    *key = 0;
+    *offset = 0;
+    return INVALID_2022;
+}
+
+/*runs through a state machine to determine the escape sequence - codepage correspondance
+ */
+static void
+changeState_2022(UConverter* _this,
+                const char** source,
+                const char* sourceLimit,
+                Variant2022 var,
+                UErrorCode* err){
+    UCNV_TableStates_2022 value;
+    UConverterDataISO2022* myData2022 = ((UConverterDataISO2022*)_this->extraInfo);
+    uint32_t key = myData2022->key;
+    int32_t offset = 0;
+    int8_t initialToULength = _this->toULength;
+    char c;
+
+    value = VALID_NON_TERMINAL_2022;
+    while (*source < sourceLimit) {
+        c = *(*source)++;
+        _this->toUBytes[_this->toULength++]=(uint8_t)c;
+        value = getKey_2022(c,(int32_t *) &key, &offset);
+
+        switch (value){
+
+        case VALID_NON_TERMINAL_2022 :
+            /* continue with the loop */
+            break;
+
+        case VALID_TERMINAL_2022:
+            key = 0;
+            goto DONE;
+
+        case INVALID_2022:
+            goto DONE;
+
+        case VALID_MAYBE_TERMINAL_2022:
+#ifdef U_ENABLE_GENERIC_ISO_2022
+            /* ESC ( B is ambiguous only for ISO_2022 itself */
+            if(var == ISO_2022) {
+                /* discard toUBytes[] for ESC ( B because this sequence is correct and complete */
+                _this->toULength = 0;
+
+                /* TODO need to indicate that ESC ( B was seen; if failure, then need to replay from source or from MBCS-style replay */
+
+                /* continue with the loop */
+                value = VALID_NON_TERMINAL_2022;
+                break;
+            } else
+#endif
+            {
+                /* not ISO_2022 itself, finish here */
+                value = VALID_TERMINAL_2022;
+                key = 0;
+                goto DONE;
+            }
+        }
+    }
+
+DONE:
+    myData2022->key = key;
+
+    if (value == VALID_NON_TERMINAL_2022) {
+        /* indicate that the escape sequence is incomplete: key!=0 */
+        return;
+    } else if (value == INVALID_2022 ) {
+        *err = U_ILLEGAL_ESCAPE_SEQUENCE;
+    } else /* value == VALID_TERMINAL_2022 */ {
+        switch(var){
+#ifdef U_ENABLE_GENERIC_ISO_2022
+        case ISO_2022:
+        {
+            const char *chosenConverterName = escSeqStateTable_Result_2022[offset];
+            if(chosenConverterName == NULL) {
+                /* SS2 or SS3 */
+                *err = U_UNSUPPORTED_ESCAPE_SEQUENCE;
+                _this->toUCallbackReason = UCNV_UNASSIGNED;
+                return;
+            }
+
+            _this->mode = UCNV_SI;
+            ucnv_close(myData2022->currentConverter);
+            myData2022->currentConverter = myUConverter = ucnv_open(chosenConverterName, err);
+            if(U_SUCCESS(*err)) {
+                myUConverter->fromCharErrorBehaviour = UCNV_TO_U_CALLBACK_STOP;
+                _this->mode = UCNV_SO;
+            }
+            break;
+        }
+#endif
+        case ISO_2022_JP:
+            {
+                StateEnum tempState=(StateEnum)nextStateToUnicodeJP[offset];
+                switch(tempState) {
+                case INVALID_STATE:
+                    *err = U_UNSUPPORTED_ESCAPE_SEQUENCE;
+                    break;
+                case SS2_STATE:
+                    if(myData2022->toU2022State.cs[2]!=0) {
+                        if(myData2022->toU2022State.g<2) {
+                            myData2022->toU2022State.prevG=myData2022->toU2022State.g;
+                        }
+                        myData2022->toU2022State.g=2;
+                    } else {
+                        /* illegal to have SS2 before a matching designator */
+                        *err = U_ILLEGAL_ESCAPE_SEQUENCE;
+                    }
+                    break;
+                /* case SS3_STATE: not used in ISO-2022-JP-x */
+                case ISO8859_1:
+                case ISO8859_7:
+                    if((jpCharsetMasks[myData2022->version] & CSM(tempState)) == 0) {
+                        *err = U_UNSUPPORTED_ESCAPE_SEQUENCE;
+                    } else {
+                        /* G2 charset for SS2 */
+                        myData2022->toU2022State.cs[2]=(int8_t)tempState;
+                    }
+                    break;
+                default:
+                    if((jpCharsetMasks[myData2022->version] & CSM(tempState)) == 0) {
+                        *err = U_UNSUPPORTED_ESCAPE_SEQUENCE;
+                    } else {
+                        /* G0 charset */
+                        myData2022->toU2022State.cs[0]=(int8_t)tempState;
+                    }
+                    break;
+                }
+            }
+            break;
+        case ISO_2022_CN:
+            {
+                StateEnum tempState=(StateEnum)nextStateToUnicodeCN[offset];
+                switch(tempState) {
+                case INVALID_STATE:
+                    *err = U_UNSUPPORTED_ESCAPE_SEQUENCE;
+                    break;
+                case SS2_STATE:
+                    if(myData2022->toU2022State.cs[2]!=0) {
+                        if(myData2022->toU2022State.g<2) {
+                            myData2022->toU2022State.prevG=myData2022->toU2022State.g;
+                        }
+                        myData2022->toU2022State.g=2;
+                    } else {
+                        /* illegal to have SS2 before a matching designator */
+                        *err = U_ILLEGAL_ESCAPE_SEQUENCE;
+                    }
+                    break;
+                case SS3_STATE:
+                    if(myData2022->toU2022State.cs[3]!=0) {
+                        if(myData2022->toU2022State.g<2) {
+                            myData2022->toU2022State.prevG=myData2022->toU2022State.g;
+                        }
+                        myData2022->toU2022State.g=3;
+                    } else {
+                        /* illegal to have SS3 before a matching designator */
+                        *err = U_ILLEGAL_ESCAPE_SEQUENCE;
+                    }
+                    break;
+                case ISO_IR_165:
+                    if(myData2022->version==0) {
+                        *err = U_UNSUPPORTED_ESCAPE_SEQUENCE;
+                        break;
+                    }
+                    /*fall through*/
+                case GB2312_1:
+                    /*fall through*/
+                case CNS_11643_1:
+                    myData2022->toU2022State.cs[1]=(int8_t)tempState;
+                    break;
+                case CNS_11643_2:
+                    myData2022->toU2022State.cs[2]=(int8_t)tempState;
+                    break;
+                default:
+                    /* other CNS 11643 planes */
+                    if(myData2022->version==0) {
+                        *err = U_UNSUPPORTED_ESCAPE_SEQUENCE;
+                    } else {
+                       myData2022->toU2022State.cs[3]=(int8_t)tempState;
+                    }
+                    break;
+                }
+            }
+            break;
+        case ISO_2022_KR:
+            if(offset==0x30){
+                /* nothing to be done, just accept this one escape sequence */
+            } else {
+                *err = U_UNSUPPORTED_ESCAPE_SEQUENCE;
+            }
+            break;
+
+        default:
+            *err = U_ILLEGAL_ESCAPE_SEQUENCE;
+            break;
+        }
+    }
+    if(U_SUCCESS(*err)) {
+        _this->toULength = 0;
+    } else if(*err==U_ILLEGAL_ESCAPE_SEQUENCE) {
+        if(_this->toULength>1) {
+            /*
+             * Ticket 5691: consistent illegal sequences:
+             * - We include at least the first byte (ESC) in the illegal sequence.
+             * - If any of the non-initial bytes could be the start of a character,
+             *   we stop the illegal sequence before the first one of those.
+             *   In escape sequences, all following bytes are "printable", that is,
+             *   unless they are completely illegal (>7f in SBCS, outside 21..7e in DBCS),
+             *   they are valid single/lead bytes.
+             *   For simplicity, we always only report the initial ESC byte as the
+             *   illegal sequence and back out all other bytes we looked at.
+             */
+            /* Back out some bytes. */
+            int8_t backOutDistance=_this->toULength-1;
+            int8_t bytesFromThisBuffer=_this->toULength-initialToULength;
+            if(backOutDistance<=bytesFromThisBuffer) {
+                /* same as initialToULength<=1 */
+                *source-=backOutDistance;
+            } else {
+                /* Back out bytes from the previous buffer: Need to replay them. */
+                _this->preToULength=(int8_t)(bytesFromThisBuffer-backOutDistance);
+                /* same as -(initialToULength-1) */
+                /* preToULength is negative! */
+                uprv_memcpy(_this->preToU, _this->toUBytes+1, -_this->preToULength);
+                *source-=bytesFromThisBuffer;
+            }
+            _this->toULength=1;
+        }
+    } else if(*err==U_UNSUPPORTED_ESCAPE_SEQUENCE) {
+        _this->toUCallbackReason = UCNV_UNASSIGNED;
+    }
+}
+
+/*Checks the characters of the buffer against valid 2022 escape sequences
+*if the match we return a pointer to the initial start of the sequence otherwise
+*we return sourceLimit
+*/
+/*for 2022 looks ahead in the stream
+ *to determine the longest possible convertible
+ *data stream
+ */
+static U_INLINE const char*
+getEndOfBuffer_2022(const char** source,
+                   const char* sourceLimit,
+                   UBool flush){
+
+    const char* mySource = *source;
+
+#ifdef U_ENABLE_GENERIC_ISO_2022
+    if (*source >= sourceLimit)
+        return sourceLimit;
+
+    do{
+
+        if (*mySource == ESC_2022){
+            int8_t i;
+            int32_t key = 0;
+            int32_t offset;
+            UCNV_TableStates_2022 value = VALID_NON_TERMINAL_2022;
+
+            /* Kludge: I could not
+            * figure out the reason for validating an escape sequence
+            * twice - once here and once in changeState_2022().
+            * is it possible to have an ESC character in a ISO2022
+            * byte stream which is valid in a code page? Is it legal?
+            */
+            for (i=0;
+            (mySource+i < sourceLimit)&&(value == VALID_NON_TERMINAL_2022);
+            i++) {
+                value =  getKey_2022(*(mySource+i), &key, &offset);
+            }
+            if (value > 0 || *mySource==ESC_2022)
+                return mySource;
+
+            if ((value == VALID_NON_TERMINAL_2022)&&(!flush) )
+                return sourceLimit;
+        }
+    }while (++mySource < sourceLimit);
+
+    return sourceLimit;
+#else
+    while(mySource < sourceLimit && *mySource != ESC_2022) {
+        ++mySource;
+    }
+    return mySource;
+#endif
+}
+
+
+/* This inline function replicates code in _MBCSFromUChar32() function in ucnvmbcs.c
+ * any future change in _MBCSFromUChar32() function should be reflected here.
+ * @return number of bytes in *value; negative number if fallback; 0 if no mapping
+ */
+static U_INLINE int32_t
+MBCS_FROM_UCHAR32_ISO2022(UConverterSharedData* sharedData,
+                                         UChar32 c,
+                                         uint32_t* value,
+                                         UBool useFallback,
+                                         int outputType)
+{
+    const int32_t *cx;
+    const uint16_t *table;
+    uint32_t stage2Entry;
+    uint32_t myValue;
+    int32_t length;
+    const uint8_t *p;
+    /*
+     * TODO(markus): Use and require new, faster MBCS conversion table structures.
+     * Use internal version of ucnv_open() that verifies that the new structures are available,
+     * else U_INTERNAL_PROGRAM_ERROR.
+     */
+    /* BMP-only codepages are stored without stage 1 entries for supplementary code points */
+    if(c<0x10000 || (sharedData->mbcs.unicodeMask&UCNV_HAS_SUPPLEMENTARY)) {
+        table=sharedData->mbcs.fromUnicodeTable;
+        stage2Entry=MBCS_STAGE_2_FROM_U(table, c);
+        /* get the bytes and the length for the output */
+        if(outputType==MBCS_OUTPUT_2){
+            myValue=MBCS_VALUE_2_FROM_STAGE_2(sharedData->mbcs.fromUnicodeBytes, stage2Entry, c);
+            if(myValue<=0xff) {
+                length=1;
+            } else {
+                length=2;
+            }
+        } else /* outputType==MBCS_OUTPUT_3 */ {
+            p=MBCS_POINTER_3_FROM_STAGE_2(sharedData->mbcs.fromUnicodeBytes, stage2Entry, c);
+            myValue=((uint32_t)*p<<16)|((uint32_t)p[1]<<8)|p[2];
+            if(myValue<=0xff) {
+                length=1;
+            } else if(myValue<=0xffff) {
+                length=2;
+            } else {
+                length=3;
+            }
+        }
+        /* is this code point assigned, or do we use fallbacks? */
+        if((stage2Entry&(1<<(16+(c&0xf))))!=0) {
+            /* assigned */
+            *value=myValue;
+            return length;
+        } else if(FROM_U_USE_FALLBACK(useFallback, c) && myValue!=0) {
+            /*
+             * We allow a 0 byte output if the "assigned" bit is set for this entry.
+             * There is no way with this data structure for fallback output
+             * to be a zero byte.
+             */
+            *value=myValue;
+            return -length;
+        }
+    }
+
+    cx=sharedData->mbcs.extIndexes;
+    if(cx!=NULL) {
+        return ucnv_extSimpleMatchFromU(cx, c, value, useFallback);
+    }
+
+    /* unassigned */
+    return 0;
+}
+
+/* This inline function replicates code in _MBCSSingleFromUChar32() function in ucnvmbcs.c
+ * any future change in _MBCSSingleFromUChar32() function should be reflected here.
+ * @param retval pointer to output byte
+ * @return 1 roundtrip byte  0 no mapping  -1 fallback byte
+ */
+static U_INLINE int32_t
+MBCS_SINGLE_FROM_UCHAR32(UConverterSharedData* sharedData,
+                                       UChar32 c,
+                                       uint32_t* retval,
+                                       UBool useFallback)
+{
+    const uint16_t *table;
+    int32_t value;
+    /* BMP-only codepages are stored without stage 1 entries for supplementary code points */
+    if(c>=0x10000 && !(sharedData->mbcs.unicodeMask&UCNV_HAS_SUPPLEMENTARY)) {
+        return 0;
+    }
+    /* convert the Unicode code point in c into codepage bytes (same as in _MBCSFromUnicodeWithOffsets) */
+    table=sharedData->mbcs.fromUnicodeTable;
+    /* get the byte for the output */
+    value=MBCS_SINGLE_RESULT_FROM_U(table, (uint16_t *)sharedData->mbcs.fromUnicodeBytes, c);
+    /* is this code point assigned, or do we use fallbacks? */
+    *retval=(uint32_t)(value&0xff);
+    if(value>=0xf00) {
+        return 1;  /* roundtrip */
+    } else if(useFallback ? value>=0x800 : value>=0xc00) {
+        return -1;  /* fallback taken */
+    } else {
+        return 0;  /* no mapping */
+    }
+}
+
+/*
+ * Check that the result is a 2-byte value with each byte in the range A1..FE
+ * (strict EUC DBCS) before accepting it and subtracting 0x80 from each byte
+ * to move it to the ISO 2022 range 21..7E.
+ * Return 0 if out of range.
+ */
+static U_INLINE uint32_t
+_2022FromGR94DBCS(uint32_t value) {
+    if( (uint16_t)(value - 0xa1a1) <= (0xfefe - 0xa1a1) &&
+        (uint8_t)(value - 0xa1) <= (0xfe - 0xa1)
+    ) {
+        return value - 0x8080;  /* shift down to 21..7e byte range */
+    } else {
+        return 0;  /* not valid for ISO 2022 */
+    }
+}
+
+#if 0 /* 5691: Call sites now check for validity. They can just += 0x8080 after that. */
+/*
+ * This method does the reverse of _2022FromGR94DBCS(). Given the 2022 code point, it returns the
+ * 2 byte value that is in the range A1..FE for each byte. Otherwise it returns the 2022 code point
+ * unchanged. 
+ */
+static U_INLINE uint32_t
+_2022ToGR94DBCS(uint32_t value) {
+    uint32_t returnValue = value + 0x8080;
+    if( (uint16_t)(returnValue - 0xa1a1) <= (0xfefe - 0xa1a1) &&
+        (uint8_t)(returnValue - 0xa1) <= (0xfe - 0xa1)) {
+        return returnValue;
+    } else {
+        return value;
+    }
+}
+#endif
+
+#ifdef U_ENABLE_GENERIC_ISO_2022
+
+/**********************************************************************************
+*  ISO-2022 Converter
+*
+*
+*/
+
+static void
+T_UConverter_toUnicode_ISO_2022_OFFSETS_LOGIC(UConverterToUnicodeArgs* args,
+                                                           UErrorCode* err){
+    const char* mySourceLimit, *realSourceLimit;
+    const char* sourceStart;
+    const UChar* myTargetStart;
+    UConverter* saveThis;
+    UConverterDataISO2022* myData;
+    int8_t length;
+
+    saveThis = args->converter;
+    myData=((UConverterDataISO2022*)(saveThis->extraInfo));
+
+    realSourceLimit = args->sourceLimit;
+    while (args->source < realSourceLimit) {
+        if(myData->key == 0) { /* are we in the middle of an escape sequence? */
+            /*Find the end of the buffer e.g : Next Escape Seq | end of Buffer*/
+            mySourceLimit = getEndOfBuffer_2022(&(args->source), realSourceLimit, args->flush);
+
+            if(args->source < mySourceLimit) {
+                if(myData->currentConverter==NULL) {
+                    myData->currentConverter = ucnv_open("ASCII",err);
+                    if(U_FAILURE(*err)){
+                        return;
+                    }
+
+                    myData->currentConverter->fromCharErrorBehaviour = UCNV_TO_U_CALLBACK_STOP;
+                    saveThis->mode = UCNV_SO;
+                }
+
+                /* convert to before the ESC or until the end of the buffer */
+                myData->isFirstBuffer=FALSE;
+                sourceStart = args->source;
+                myTargetStart = args->target;
+                args->converter = myData->currentConverter;
+                ucnv_toUnicode(args->converter,
+                    &args->target,
+                    args->targetLimit,
+                    &args->source,
+                    mySourceLimit,
+                    args->offsets,
+                    (UBool)(args->flush && mySourceLimit == realSourceLimit),
+                    err);
+                args->converter = saveThis;
+
+                if (*err == U_BUFFER_OVERFLOW_ERROR) {
+                    /* move the overflow buffer */
+                    length = saveThis->UCharErrorBufferLength = myData->currentConverter->UCharErrorBufferLength;
+                    myData->currentConverter->UCharErrorBufferLength = 0;
+                    if(length > 0) {
+                        uprv_memcpy(saveThis->UCharErrorBuffer,
+                                    myData->currentConverter->UCharErrorBuffer,
+                                    length*U_SIZEOF_UCHAR);
+                    }
+                    return;
+                }
+
+                /*
+                 * At least one of:
+                 * -Error while converting
+                 * -Done with entire buffer
+                 * -Need to write offsets or update the current offset
+                 *  (leave that up to the code in ucnv.c)
+                 *
+                 * or else we just stopped at an ESC byte and continue with changeState_2022()
+                 */
+                if (U_FAILURE(*err) ||
+                    (args->source == realSourceLimit) ||
+                    (args->offsets != NULL && (args->target != myTargetStart || args->source != sourceStart) ||
+                    (mySourceLimit < realSourceLimit && myData->currentConverter->toULength > 0))
+                ) {
+                    /* copy partial or error input for truncated detection and error handling */
+                    if(U_FAILURE(*err)) {
+                        length = saveThis->invalidCharLength = myData->currentConverter->invalidCharLength;
+                        if(length > 0) {
+                            uprv_memcpy(saveThis->invalidCharBuffer, myData->currentConverter->invalidCharBuffer, length);
+                        }
+                    } else {
+                        length = saveThis->toULength = myData->currentConverter->toULength;
+                        if(length > 0) {
+                            uprv_memcpy(saveThis->toUBytes, myData->currentConverter->toUBytes, length);
+                            if(args->source < mySourceLimit) {
+                                *err = U_TRUNCATED_CHAR_FOUND; /* truncated input before ESC */
+                            }
+                        }
+                    }
+                    return;
+                }
+            }
+        }
+
+        sourceStart = args->source;
+        changeState_2022(args->converter,
+               &(args->source),
+               realSourceLimit,
+               ISO_2022,
+               err);
+        if (U_FAILURE(*err) || (args->source != sourceStart && args->offsets != NULL)) {
+            /* let the ucnv.c code update its current offset */
+            return;
+        }
+    }
+}
+
+#endif
+
+/*
+ * To Unicode Callback helper function
+ */
+static void
+toUnicodeCallback(UConverter *cnv,
+                  const uint32_t sourceChar, const uint32_t targetUniChar,
+                  UErrorCode* err){
+    if(sourceChar>0xff){
+        cnv->toUBytes[0] = (uint8_t)(sourceChar>>8);
+        cnv->toUBytes[1] = (uint8_t)sourceChar;
+        cnv->toULength = 2;
+    }
+    else{
+        cnv->toUBytes[0] =(char) sourceChar;
+        cnv->toULength = 1;
+    }
+
+    if(targetUniChar == (missingCharMarker-1/*0xfffe*/)){
+        *err = U_INVALID_CHAR_FOUND;
+    }
+    else{
+        *err = U_ILLEGAL_CHAR_FOUND;
+    }
+}
+
+/**************************************ISO-2022-JP*************************************************/
+
+/************************************** IMPORTANT **************************************************
+* The UConverter_fromUnicode_ISO2022_JP converter does not use ucnv_fromUnicode() functions for SBCS,DBCS and
+* MBCS; instead, the values are obtained directly by calling _MBCSFromUChar32().
+* The converter iterates over each Unicode codepoint
+* to obtain the equivalent codepoints from the codepages supported. Since the source buffer is
+* processed one char at a time it would make sense to reduce the extra processing a canned converter
+* would do as far as possible.
+*
+* If the implementation of these macros or structure of sharedData struct change in the future, make
+* sure that ISO-2022 is also changed.
+***************************************************************************************************
+*/
+
+/***************************************************************************************************
+* Rules for ISO-2022-jp encoding
+* (i)   Escape sequences must be fully contained within a line they should not
+*       span new lines or CRs
+* (ii)  If the last character on a line is represented by two bytes then an ASCII or
+*       JIS-Roman character escape sequence should follow before the line terminates
+* (iii) If the first character on the line is represented by two bytes then a two
+*       byte character escape sequence should precede it
+* (iv)  If no escape sequence is encountered then the characters are ASCII
+* (v)   Latin(ISO-8859-1) and Greek(ISO-8859-7) characters must be designated to G2,
+*       and invoked with SS2 (ESC N).
+* (vi)  If there is any G0 designation in text, there must be a switch to
+*       ASCII or to JIS X 0201-Roman before a space character (but not
+*       necessarily before "ESC 4/14 2/0" or "ESC N ' '") or control
+*       characters such as tab or CRLF.
+* (vi)  Supported encodings:
+*          ASCII, JISX201, JISX208, JISX212, GB2312, KSC5601, ISO-8859-1,ISO-8859-7
+*
+*  source : RFC-1554
+*
+*          JISX201, JISX208,JISX212 : new .cnv data files created
+*          KSC5601 : alias to ibm-949 mapping table
+*          GB2312 : alias to ibm-1386 mapping table
+*          ISO-8859-1 : Algorithmic implemented as LATIN1 case
+*          ISO-8859-7 : alisas to ibm-9409 mapping table
+*/
+
+/* preference order of JP charsets */
+static const StateEnum jpCharsetPref[]={
+    ASCII,
+    JISX201,
+    ISO8859_1,
+    ISO8859_7,
+    JISX208,
+    JISX212,
+    GB2312,
+    KSC5601,
+    HWKANA_7BIT
+};
+
+/*
+ * The escape sequences must be in order of the enum constants like JISX201  = 3,
+ * not in order of jpCharsetPref[]!
+ */
+static const char escSeqChars[][6] ={
+    "\x1B\x28\x42",         /* <ESC>(B  ASCII       */
+    "\x1B\x2E\x41",         /* <ESC>.A  ISO-8859-1  */
+    "\x1B\x2E\x46",         /* <ESC>.F  ISO-8859-7  */
+    "\x1B\x28\x4A",         /* <ESC>(J  JISX-201    */
+    "\x1B\x24\x42",         /* <ESC>$B  JISX-208    */
+    "\x1B\x24\x28\x44",     /* <ESC>$(D JISX-212    */
+    "\x1B\x24\x41",         /* <ESC>$A  GB2312      */
+    "\x1B\x24\x28\x43",     /* <ESC>$(C KSC5601     */
+    "\x1B\x28\x49"          /* <ESC>(I  HWKANA_7BIT */
+
+};
+static  const int8_t escSeqCharsLen[] ={
+    3, /* length of <ESC>(B  ASCII       */
+    3, /* length of <ESC>.A  ISO-8859-1  */
+    3, /* length of <ESC>.F  ISO-8859-7  */
+    3, /* length of <ESC>(J  JISX-201    */
+    3, /* length of <ESC>$B  JISX-208    */
+    4, /* length of <ESC>$(D JISX-212    */
+    3, /* length of <ESC>$A  GB2312      */
+    4, /* length of <ESC>$(C KSC5601     */
+    3  /* length of <ESC>(I  HWKANA_7BIT */
+};
+
+/*
+* The iteration over various code pages works this way:
+* i)   Get the currentState from myConverterData->currentState
+* ii)  Check if the character is mapped to a valid character in the currentState
+*      Yes ->  a) set the initIterState to currentState
+*       b) remain in this state until an invalid character is found
+*      No  ->  a) go to the next code page and find the character
+* iii) Before changing the state increment the current state check if the current state
+*      is equal to the intitIteration state
+*      Yes ->  A character that cannot be represented in any of the supported encodings
+*       break and return a U_INVALID_CHARACTER error
+*      No  ->  Continue and find the character in next code page
+*
+*
+* TODO: Implement a priority technique where the users are allowed to set the priority of code pages
+*/
+
+/* Map 00..7F to Unicode according to JIS X 0201. */
+static U_INLINE uint32_t
+jisx201ToU(uint32_t value) {
+    if(value < 0x5c) {
+        return value;
+    } else if(value == 0x5c) {
+        return 0xa5;
+    } else if(value == 0x7e) {
+        return 0x203e;
+    } else /* value <= 0x7f */ {
+        return value;
+    }
+}
+
+/* Map Unicode to 00..7F according to JIS X 0201. Return U+FFFE if unmappable. */
+static U_INLINE uint32_t
+jisx201FromU(uint32_t value) {
+    if(value<=0x7f) {
+        if(value!=0x5c && value!=0x7e) {
+            return value;
+        }
+    } else if(value==0xa5) {
+        return 0x5c;
+    } else if(value==0x203e) {
+        return 0x7e;
+    }
+    return 0xfffe;
+}
+
+/*
+ * Take a valid Shift-JIS byte pair, check that it is in the range corresponding
+ * to JIS X 0208, and convert it to a pair of 21..7E bytes.
+ * Return 0 if the byte pair is out of range.
+ */
+static U_INLINE uint32_t
+_2022FromSJIS(uint32_t value) {
+    uint8_t trail;
+
+    if(value > 0xEFFC) {
+        return 0;  /* beyond JIS X 0208 */
+    }
+
+    trail = (uint8_t)value;
+
+    value &= 0xff00;  /* lead byte */
+    if(value <= 0x9f00) {
+        value -= 0x7000;
+    } else /* 0xe000 <= value <= 0xef00 */ {
+        value -= 0xb000;
+    }
+    value <<= 1;
+
+    if(trail <= 0x9e) {
+        value -= 0x100;
+        if(trail <= 0x7e) {
+            value |= trail - 0x1f;
+        } else {
+            value |= trail - 0x20;
+        }
+    } else /* trail <= 0xfc */ {
+        value |= trail - 0x7e;
+    }
+    return value;
+}
+
+/*
+ * Convert a pair of JIS X 0208 21..7E bytes to Shift-JIS.
+ * If either byte is outside 21..7E make sure that the result is not valid
+ * for Shift-JIS so that the converter catches it.
+ * Some invalid byte values already turn into equally invalid Shift-JIS
+ * byte values and need not be tested explicitly.
+ */
+static U_INLINE void
+_2022ToSJIS(uint8_t c1, uint8_t c2, char bytes[2]) {
+    if(c1&1) {
+        ++c1;
+        if(c2 <= 0x5f) {
+            c2 += 0x1f;
+        } else if(c2 <= 0x7e) {
+            c2 += 0x20;
+        } else {
+            c2 = 0;  /* invalid */
+        }
+    } else {
+        if((uint8_t)(c2-0x21) <= ((0x7e)-0x21)) {
+            c2 += 0x7e;
+        } else {
+            c2 = 0;  /* invalid */
+        }
+    }
+    c1 >>= 1;
+    if(c1 <= 0x2f) {
+        c1 += 0x70;
+    } else if(c1 <= 0x3f) {
+        c1 += 0xb0;
+    } else {
+        c1 = 0;  /* invalid */
+    }
+    bytes[0] = (char)c1;
+    bytes[1] = (char)c2;
+}
+
+/*
+ * JIS X 0208 has fallbacks from Unicode half-width Katakana to full-width (DBCS)
+ * Katakana.
+ * Now that we use a Shift-JIS table for JIS X 0208 we need to hardcode these fallbacks
+ * because Shift-JIS roundtrips half-width Katakana to single bytes.
+ * These were the only fallbacks in ICU's jisx-208.ucm file.
+ */
+static const uint16_t hwkana_fb[HWKANA_END - HWKANA_START + 1] = {
+    0x2123,  /* U+FF61 */
+    0x2156,
+    0x2157,
+    0x2122,
+    0x2126,
+    0x2572,
+    0x2521,
+    0x2523,
+    0x2525,
+    0x2527,
+    0x2529,
+    0x2563,
+    0x2565,
+    0x2567,
+    0x2543,
+    0x213C,  /* U+FF70 */
+    0x2522,
+    0x2524,
+    0x2526,
+    0x2528,
+    0x252A,
+    0x252B,
+    0x252D,
+    0x252F,
+    0x2531,
+    0x2533,
+    0x2535,
+    0x2537,
+    0x2539,
+    0x253B,
+    0x253D,
+    0x253F,  /* U+FF80 */
+    0x2541,
+    0x2544,
+    0x2546,
+    0x2548,
+    0x254A,
+    0x254B,
+    0x254C,
+    0x254D,
+    0x254E,
+    0x254F,
+    0x2552,
+    0x2555,
+    0x2558,
+    0x255B,
+    0x255E,
+    0x255F,  /* U+FF90 */
+    0x2560,
+    0x2561,
+    0x2562,
+    0x2564,
+    0x2566,
+    0x2568,
+    0x2569,
+    0x256A,
+    0x256B,
+    0x256C,
+    0x256D,
+    0x256F,
+    0x2573,
+    0x212B,
+    0x212C   /* U+FF9F */
+};
+
+static void
+UConverter_fromUnicode_ISO_2022_JP_OFFSETS_LOGIC(UConverterFromUnicodeArgs* args, UErrorCode* err) {
+    UConverter *cnv = args->converter;
+    UConverterDataISO2022 *converterData;
+    ISO2022State *pFromU2022State;
+    uint8_t *target = (uint8_t *) args->target;
+    const uint8_t *targetLimit = (const uint8_t *) args->targetLimit;
+    const UChar* source = args->source;
+    const UChar* sourceLimit = args->sourceLimit;
+    int32_t* offsets = args->offsets;
+    UChar32 sourceChar;
+    char buffer[8];
+    int32_t len, outLen;
+    int8_t choices[10];
+    int32_t choiceCount;
+    uint32_t targetValue = 0;
+    UBool useFallback;
+
+    int32_t i;
+    int8_t cs, g;
+
+    /* set up the state */
+    converterData     = (UConverterDataISO2022*)cnv->extraInfo;
+    pFromU2022State   = &converterData->fromU2022State;
+
+    choiceCount = 0;
+
+    /* check if the last codepoint of previous buffer was a lead surrogate*/
+    if((sourceChar = cnv->fromUChar32)!=0 && target< targetLimit) {
+        goto getTrail;
+    }
+
+    while(source < sourceLimit) {
+        if(target < targetLimit) {
+
+            sourceChar  = *(source++);
+            /*check if the char is a First surrogate*/
+            if(UTF_IS_SURROGATE(sourceChar)) {
+                if(UTF_IS_SURROGATE_FIRST(sourceChar)) {
+getTrail:
+                    /*look ahead to find the trail surrogate*/
+                    if(source < sourceLimit) {
+                        /* test the following code unit */
+                        UChar trail=(UChar) *source;
+                        if(UTF_IS_SECOND_SURROGATE(trail)) {
+                            source++;
+                            sourceChar=UTF16_GET_PAIR_VALUE(sourceChar, trail);
+                            cnv->fromUChar32=0x00;
+                            /* convert this supplementary code point */
+                            /* exit this condition tree */
+                        } else {
+                            /* this is an unmatched lead code unit (1st surrogate) */
+                            /* callback(illegal) */
+                            *err=U_ILLEGAL_CHAR_FOUND;
+                            cnv->fromUChar32=sourceChar;
+                            break;
+                        }
+                    } else {
+                        /* no more input */
+                        cnv->fromUChar32=sourceChar;
+                        break;
+                    }
+                } else {
+                    /* this is an unmatched trail code unit (2nd surrogate) */
+                    /* callback(illegal) */
+                    *err=U_ILLEGAL_CHAR_FOUND;
+                    cnv->fromUChar32=sourceChar;
+                    break;
+                }
+            }
+
+            /* do not convert SO/SI/ESC */
+            if(IS_2022_CONTROL(sourceChar)) {
+                /* callback(illegal) */
+                *err=U_ILLEGAL_CHAR_FOUND;
+                cnv->fromUChar32=sourceChar;
+                break;
+            }
+
+            /* do the conversion */
+
+            if(choiceCount == 0) {
+                uint16_t csm;
+
+                /*
+                 * The csm variable keeps track of which charsets are allowed
+                 * and not used yet while building the choices[].
+                 */
+                csm = jpCharsetMasks[converterData->version];
+                choiceCount = 0;
+
+                /* JIS7/8: try single-byte half-width Katakana before JISX208 */
+                if(converterData->version == 3 || converterData->version == 4) {
+                    choices[choiceCount++] = (int8_t)HWKANA_7BIT;
+                }
+                /* Do not try single-byte half-width Katakana for other versions. */
+                csm &= ~CSM(HWKANA_7BIT);
+
+                /* try the current G0 charset */
+                choices[choiceCount++] = cs = pFromU2022State->cs[0];
+                csm &= ~CSM(cs);
+
+                /* try the current G2 charset */
+                if((cs = pFromU2022State->cs[2]) != 0) {
+                    choices[choiceCount++] = cs;
+                    csm &= ~CSM(cs);
+                }
+
+                /* try all the other possible charsets */
+                for(i = 0; i < LENGTHOF(jpCharsetPref); ++i) {
+                    cs = (int8_t)jpCharsetPref[i];
+                    if(CSM(cs) & csm) {
+                        choices[choiceCount++] = cs;
+                        csm &= ~CSM(cs);
+                    }
+                }
+            }
+
+            cs = g = 0;
+            /*
+             * len==0: no mapping found yet
+             * len<0: found a fallback result: continue looking for a roundtrip but no further fallbacks
+             * len>0: found a roundtrip result, done
+             */
+            len = 0;
+            /*
+             * We will turn off useFallback after finding a fallback,
+             * but we still get fallbacks from PUA code points as usual.
+             * Therefore, we will also need to check that we don't overwrite
+             * an early fallback with a later one.
+             */
+            useFallback = cnv->useFallback;
+
+            for(i = 0; i < choiceCount && len <= 0; ++i) {
+                uint32_t value;
+                int32_t len2;
+                int8_t cs0 = choices[i];
+                switch(cs0) {
+                case ASCII:
+                    if(sourceChar <= 0x7f) {
+                        targetValue = (uint32_t)sourceChar;
+                        len = 1;
+                        cs = cs0;
+                        g = 0;
+                    }
+                    break;
+                case ISO8859_1:
+                    if(GR96_START <= sourceChar && sourceChar <= GR96_END) {
+                        targetValue = (uint32_t)sourceChar - 0x80;
+                        len = 1;
+                        cs = cs0;
+                        g = 2;
+                    }
+                    break;
+                case HWKANA_7BIT:
+                    if((uint32_t)(sourceChar - HWKANA_START) <= (HWKANA_END - HWKANA_START)) {
+                        if(converterData->version==3) {
+                            /* JIS7: use G1 (SO) */
+                            /* Shift U+FF61..U+FF9F to bytes 21..5F. */
+                            targetValue = (uint32_t)(sourceChar - (HWKANA_START - 0x21));
+                            len = 1;
+                            pFromU2022State->cs[1] = cs = cs0; /* do not output an escape sequence */
+                            g = 1;
+                        } else if(converterData->version==4) {
+                            /* JIS8: use 8-bit bytes with any single-byte charset, see escape sequence output below */
+                            /* Shift U+FF61..U+FF9F to bytes A1..DF. */
+                            targetValue = (uint32_t)(sourceChar - (HWKANA_START - 0xa1));
+                            len = 1;
+
+                            cs = pFromU2022State->cs[0];
+                            if(IS_JP_DBCS(cs)) {
+                                /* switch from a DBCS charset to JISX201 */
+                                cs = (int8_t)JISX201;
+                            }
+                            /* else stay in the current G0 charset */
+                            g = 0;
+                        }
+                        /* else do not use HWKANA_7BIT with other versions */
+                    }
+                    break;
+                case JISX201:
+                    /* G0 SBCS */
+                    value = jisx201FromU(sourceChar);
+                    if(value <= 0x7f) {
+                        targetValue = value;
+                        len = 1;
+